include/oox/export/shapes.hxx          |    1 +
 oox/source/export/shapes.cxx           |   10 ++++++++++
 sc/qa/unit/data/xlsx/tdf165655.xlsx    |binary
 sc/qa/unit/subsequent_export_test4.cxx |   16 ++++++++++++++++
 sc/source/filter/xcl97/xcl97rec.cxx    |    7 +++++++
 5 files changed, 34 insertions(+)

New commits:
commit ab45b8d9959f8f392a10d0874c50f26b816a4da8
Author:     Aron Budea <aron.bu...@collabora.com>
AuthorDate: Mon Mar 10 04:08:31 2025 +1030
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Mon Mar 31 21:58:03 2025 +0200

    tdf#165655 oox: don't export incomplete shape data coming from VML
    
    Some export was added in fd238380ae7820f12ac1f7c52d0f7180a93f3ba3.
    This can result in only anchor pointers and no other data
    saved for certain shapes having no export code, making it an
    invalid file.
    
    Change-Id: I81bf513b6ebaa9f6456a26ccbc3276e019551eca
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182699
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Tested-by: Jenkins

diff --git a/include/oox/export/shapes.hxx b/include/oox/export/shapes.hxx
index 646d462e827b..bf37a0f8f857 100644
--- a/include/oox/export/shapes.hxx
+++ b/include/oox/export/shapes.hxx
@@ -116,6 +116,7 @@ public:
     void SetURLTranslator(const std::shared_ptr<URLTransformer>& pTransformer);
 
     static bool         NonEmptyText( const css::uno::Reference< 
css::uno::XInterface >& xIface );
+    static bool         IsShapeTypeKnown( const css::uno::Reference< 
css::drawing::XShape >& xShape );
 
     ShapeExport&
                         WritePolyPolygonShape( const css::uno::Reference< 
css::drawing::XShape >& xShape, bool bClosed );
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index 261bd5a24040..f05e9212a952 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -2189,6 +2189,16 @@ constexpr auto constMap = 
frozen::make_unordered_map<std::u16string_view, ShapeC
 
 } // end anonymous namespace
 
+
+bool ShapeExport::IsShapeTypeKnown(const Reference<XShape>& xShape)
+{
+    if (!xShape)
+        return false;
+
+    const OUString sShapeType = xShape->getShapeType();
+    return constMap.contains(sShapeType);
+}
+
 ShapeExport& ShapeExport::WriteShape( const Reference< XShape >& xShape )
 {
     if (!xShape)
diff --git a/sc/qa/unit/data/xlsx/tdf165655.xlsx 
b/sc/qa/unit/data/xlsx/tdf165655.xlsx
new file mode 100644
index 000000000000..620b68a4b956
Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf165655.xlsx differ
diff --git a/sc/qa/unit/subsequent_export_test4.cxx 
b/sc/qa/unit/subsequent_export_test4.cxx
index 87a225a2cf77..ad3642a666f3 100644
--- a/sc/qa/unit/subsequent_export_test4.cxx
+++ b/sc/qa/unit/subsequent_export_test4.cxx
@@ -2193,6 +2193,22 @@ CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf165503)
     CPPUNIT_ASSERT_EQUAL(0, aNodes);
 }
 
+CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf165655)
+{
+    createScDoc("xlsx/tdf165655.xlsx");
+
+    save(u"Calc Office Open XML"_ustr);
+
+    xmlDocUniquePtr pDrawing = parseExport(u"xl/drawings/drawing1.xml"_ustr);
+    CPPUNIT_ASSERT(pDrawing);
+
+    // Original has 3 drawingML and 1 VML objects
+    // Not sure if the VML dropdown should be exported, but as long as it 
cannot be
+    //  exported properly, it should not be exported at all (only the 3 
drawingMLs)
+    const int aNodes = countXPathNodes(pDrawing, 
"/xdr:wsDr/xdr:twoCellAnchor");
+    CPPUNIT_ASSERT_EQUAL(3, aNodes);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xcl97/xcl97rec.cxx 
b/sc/source/filter/xcl97/xcl97rec.cxx
index 76b47c43bf10..e07e84c5e39d 100644
--- a/sc/source/filter/xcl97/xcl97rec.cxx
+++ b/sc/source/filter/xcl97/xcl97rec.cxx
@@ -1304,6 +1304,13 @@ bool ScURLTransformer::isExternalURL(const OUString& 
rURL) const
 
 void XclObjAny::SaveXml( XclExpXmlStream& rStrm )
 {
+    // Return early if unknown shape type, otherwise bogus drawing XML gets 
written
+    if (!ShapeExport::IsShapeTypeKnown(mxShape))
+    {
+        SAL_INFO("sc.filter", "unknown shape");
+        return;
+    }
+
     // Do not output any of the detective shapes and validation circles.
     SdrObject* pObject = SdrObject::getSdrObjectFromXShape(mxShape);
     if (pObject)

Reply via email to