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 9599d84a704d47eda29d571bfad10a13bff24fb4 Author: Aron Budea <[email protected]> AuthorDate: Mon Mar 10 04:08:31 2025 +1030 Commit: Mike Kaganski <[email protected]> CommitDate: Thu Apr 3 10:08:15 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 <[email protected]> Tested-by: Jenkins (cherry picked from commit ab45b8d9959f8f392a10d0874c50f26b816a4da8) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183597 Tested-by: Jenkins CollaboraOffice <[email protected]> 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 8a9589b8e7f5..31a29ccec8c9 100644 --- a/oox/source/export/shapes.cxx +++ b/oox/source/export/shapes.cxx @@ -2103,6 +2103,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.find(sShapeType) != constMap.end(); +} + 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 e8ca463e8441..0c0c5359978e 100644 --- a/sc/qa/unit/subsequent_export_test4.cxx +++ b/sc/qa/unit/subsequent_export_test4.cxx @@ -1894,6 +1894,22 @@ CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf165503) CPPUNIT_ASSERT_EQUAL(0, aNodes); } +CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf165655) +{ + createScDoc("xlsx/tdf165655.xlsx"); + + save("Calc Office Open XML"); + + xmlDocUniquePtr pDrawing = parseExport("xl/drawings/drawing1.xml"); + 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"_ostr); + 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 e9ae7bdeba42..09fa18036f09 100644 --- a/sc/source/filter/xcl97/xcl97rec.cxx +++ b/sc/source/filter/xcl97/xcl97rec.cxx @@ -1305,6 +1305,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)
