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 3eba98e51e8718bd74f98392cb80c98d438278d5 Author: Aron Budea <[email protected]> AuthorDate: Mon Mar 10 04:08:31 2025 +1030 Commit: Mike Kaganski <[email protected]> CommitDate: Wed Apr 2 07:29:40 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/+/183566 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 0fdf240d0850..d8c396382217 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 4d14b4a7a5a4..6e370b1f5a3c 100644 --- a/sc/qa/unit/subsequent_export_test4.cxx +++ b/sc/qa/unit/subsequent_export_test4.cxx @@ -2160,6 +2160,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)
