oox/source/core/relations.cxx                |   10 ++++++++++
 oox/source/drawingml/graphicshapecontext.cxx |   14 +++++++++++---
 oox/source/ppt/slidefragmenthandler.cxx      |   11 +++++++----
 sd/qa/unit/data/pptx/tdf169781.pptx          |binary
 sd/qa/unit/export-tests-ooxml3.cxx           |   19 +++++++++++++++++++
 5 files changed, 47 insertions(+), 7 deletions(-)

New commits:
commit 76e2b197bd7b01c2af7f7ed780e8624c7c40e1fd
Author:     Karthik Godha <[email protected]>
AuthorDate: Mon Dec 1 16:28:46 2025 +0530
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Dec 2 11:55:52 2025 +0100

    tdf#169781: PPTX legacy VML files are not imported
    
    Change-Id: Id6eeeab193ac0ed6ff60991508466ffd58005ea7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194875
    Reviewed-by: Michael Stahl <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/oox/source/core/relations.cxx b/oox/source/core/relations.cxx
index cda3f451094a..2fd3f4e5d103 100644
--- a/oox/source/core/relations.cxx
+++ b/oox/source/core/relations.cxx
@@ -54,6 +54,11 @@ OUString 
createOfficeDocRelationTypeStrict(std::u16string_view rType)
     return 
OUString::Concat("http://purl.oclc.org/ooxml/officeDocument/relationships/";) + 
rType;
 }
 
+OUString createMSOfficeRelationType(std::u16string_view rType)
+{
+    return 
OUString::Concat("http://schemas.microsoft.com/office/2006/relationships/";) + 
rType;
+}
+
 }
 
 Relations::Relations( OUString aFragmentPath )
@@ -150,6 +155,11 @@ OUString 
Relations::getFragmentPathFromFirstTypeFromOfficeDoc( std::u16string_vi
     {
         OUString aStrictType = createOfficeDocRelationTypeStrict(rType);
         pRelation = getRelationFromFirstType( aStrictType );
+        if (!pRelation)
+        {
+            OUString aMicrosoftType = createMSOfficeRelationType(rType);
+            pRelation = getRelationFromFirstType(aMicrosoftType);
+        }
     }
     return pRelation ? getFragmentPathFromRelation( *pRelation ) : OUString();
 }
diff --git a/oox/source/drawingml/graphicshapecontext.cxx 
b/oox/source/drawingml/graphicshapecontext.cxx
index 4753eb9e3b19..45dbc656e6bb 100644
--- a/oox/source/drawingml/graphicshapecontext.cxx
+++ b/oox/source/drawingml/graphicshapecontext.cxx
@@ -35,6 +35,7 @@
 #include <oox/core/xmlfilterbase.hxx>
 #include <oox/helper/attributelist.hxx>
 #include <oox/vml/vmldrawing.hxx>
+#include <oox/vml/vmlshapecontainer.hxx>
 #include <drawingml/transform2dcontext.hxx>
 #include <oox/ppt/pptshapegroupcontext.hxx>
 #include <oox/token/namespaces.hxx>
@@ -257,9 +258,16 @@ void OleObjectGraphicDataContext::onEndElement()
 {
     if( getCurrentElement() == PPT_TOKEN( oleObj ) && !isMCEStateEmpty() )
     {
-        if (getMCEState() == MCE_STATE::FoundChoice && 
!mrOleObjectInfo.mbHasPicture
-            && mrOleObjectInfo.maShapeId.isEmpty())
-            setMCEState( MCE_STATE::Started );
+        if (getMCEState() == MCE_STATE::FoundChoice && 
!mrOleObjectInfo.mbHasPicture)
+        {
+            // Use mcFallback if Shape ID is invalid
+            if (!mrOleObjectInfo.maShapeId.isEmpty())
+                if (::oox::vml::Drawing* pVmlDrawing = 
getFilter().getVmlDrawing())
+                    if 
(pVmlDrawing->getShapes().getShapeById(mrOleObjectInfo.maShapeId))
+                        return;
+
+            setMCEState(MCE_STATE::Started);
+        }
     }
 }
 
diff --git a/oox/source/ppt/slidefragmenthandler.cxx 
b/oox/source/ppt/slidefragmenthandler.cxx
index ee87d752a65f..44cf7a6a4c46 100644
--- a/oox/source/ppt/slidefragmenthandler.cxx
+++ b/oox/source/ppt/slidefragmenthandler.cxx
@@ -57,10 +57,13 @@ SlideFragmentHandler::SlideFragmentHandler( XmlFilterBase& 
rFilter, const OUStri
 , mpSlidePersistPtr( pPersistPtr )
 , meShapeLocation( eShapeLocation )
 {
-    OUString aVMLDrawingFragmentPath = 
getFragmentPathFromFirstTypeFromOfficeDoc( u"vmlDrawing" );
-    if( !aVMLDrawingFragmentPath.isEmpty() )
-        getFilter().importFragment( new oox::vml::DrawingFragment(
-            getFilter(), aVMLDrawingFragmentPath, *pPersistPtr->getDrawing() ) 
);
+    OUString aVMLPath = 
getFragmentPathFromFirstTypeFromOfficeDoc(u"vmlDrawing");
+    if (aVMLPath.isEmpty())
+        aVMLPath = getFragmentPathFromFirstTypeFromOfficeDoc(u"legacyDrawing");
+
+    if (!aVMLPath.isEmpty())
+        getFilter().importFragment(
+            new oox::vml::DrawingFragment(getFilter(), aVMLPath, 
*pPersistPtr->getDrawing()));
 }
 
 SlideFragmentHandler::~SlideFragmentHandler()
diff --git a/sd/qa/unit/data/pptx/tdf169781.pptx 
b/sd/qa/unit/data/pptx/tdf169781.pptx
new file mode 100644
index 000000000000..96d0032aa894
Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf169781.pptx differ
diff --git a/sd/qa/unit/export-tests-ooxml3.cxx 
b/sd/qa/unit/export-tests-ooxml3.cxx
index 0d43d3d355eb..326259a3ad94 100644
--- a/sd/qa/unit/export-tests-ooxml3.cxx
+++ b/sd/qa/unit/export-tests-ooxml3.cxx
@@ -1093,6 +1093,25 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testTdf168736)
     assertXPath(pXmlDocRels, "/rels:Relationships/rels:Relationship[1]", 
"Target", u"slide1.xml");
 }
 
+CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testTdf169781)
+{
+    createSdImpressDoc("pptx/tdf169781.pptx");
+    save(u"Impress Office Open XML"_ustr);
+
+    xmlDocUniquePtr pXmlDoc1 = parseExport(u"ppt/slides/slide1.xml"_ustr);
+    xmlDocUniquePtr pXmlDoc2 = parseExport(u"ppt/slides/slide2.xml"_ustr);
+
+    // Without the fix in place, this test would have failed with
+    // - Expected: 1
+    // - Actual  : 0
+    assertXPath(pXmlDoc1,
+                
"/p:sld/p:cSld/p:spTree/p:graphicFrame[2]/a:graphic/a:graphicData/p:oleObj/p:pic",
+                1);
+    assertXPath(pXmlDoc2,
+                
"/p:sld/p:cSld/p:spTree/p:graphicFrame[2]/a:graphic/a:graphicData/p:oleObj/p:pic",
+                1);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to