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 0df3f8152ef15847b78bb2b48ca74ffaa70529c5 Author: Aron Budea <aron.bu...@collabora.com> AuthorDate: Mon Mar 10 04:08:31 2025 +1030 Commit: Adolfo Jayme Barrientos <fit...@ubuntu.com> CommitDate: Thu Apr 3 01:02:50 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 (cherry picked from commit ab45b8d9959f8f392a10d0874c50f26b816a4da8) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183567 Reviewed-by: Adolfo Jayme Barrientos <fit...@ubuntu.com> 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 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)