include/oox/export/shapes.hxx | 2 ++ oox/source/export/shapes.cxx | 36 ++++++++++++++++++++++++++++++++++++ sc/source/filter/xcl97/xcl97rec.cxx | 6 +++--- 3 files changed, 41 insertions(+), 3 deletions(-)
New commits: commit 13d3110c0116b6ce9d3dc59b6523902d461143a7 Author: Justin Luth <[email protected]> AuthorDate: Tue Jan 20 13:51:47 2026 -0500 Commit: Justin Luth <[email protected]> CommitDate: Thu Jan 22 14:10:19 2026 +0100 mso-test tdf#73254 xlsx export: invalid xdr:twoCellAnchor The example document fdo73254-1.xls was being reported by MS Excel as corrupt after LO saved it as XLSX. xdr:twoCellAnchor has mandatory subelements so we can't start one unless we have a valid graphic/URL. Fortunately, it is not corrupt to have an empty drawing1.xml containing only a <xdr:wsDr/>. That would have been practically impossible to avoid. Change-Id: Ia0251eb0cee1798cbeb1b8d4f545537ab2485668 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197699 Reviewed-by: Justin Luth <[email protected]> Tested-by: Jenkins diff --git a/include/oox/export/shapes.hxx b/include/oox/export/shapes.hxx index 1b37ec0cf7df..8956d587749f 100644 --- a/include/oox/export/shapes.hxx +++ b/include/oox/export/shapes.hxx @@ -113,6 +113,8 @@ public: static bool NonEmptyText( const css::uno::Reference< css::uno::XInterface >& xIface ); static bool IsShapeTypeKnown( const css::uno::Reference< css::drawing::XShape >& xShape ); + static bool IsValidShape(const css::uno::Reference<css::drawing::XShape>& xShape, + DocumentType eDocumentType); 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 9f5a4d6273ce..29dba9826903 100644 --- a/oox/source/export/shapes.cxx +++ b/oox/source/export/shapes.cxx @@ -2226,6 +2226,42 @@ bool ShapeExport::IsShapeTypeKnown(const Reference<XShape>& xShape) return constMap.contains(sShapeType); } +bool ShapeExport::IsValidShape(const Reference<XShape>& xShape, DocumentType eDocumentType) +{ + if (!xShape) + return false; + + auto aConverterIterator = constMap.find(xShape->getShapeType()); + if (aConverterIterator == constMap.end()) + return false; + + if (aConverterIterator->second == &ShapeExport::WriteGraphicObjectShape) + { + if (IsNonEmptySimpleText(xShape)) + return true; + + Reference<XPropertySet> xShapeProps(xShape, UNO_QUERY); + Reference<XPropertySetInfo> xShapePropSetInfo + = xShapeProps.is() ? xShapeProps->getPropertySetInfo() : nullptr; + if (!xShapePropSetInfo.is()) + return false; + + uno::Reference<graphic::XGraphic> xGraphic; + xShapeProps->getPropertyValue(u"Graphic"_ustr) >>= xGraphic; + + // tdf#155903 Only for PPTX. Microsoft does not support this feature in Word and Excel. + OUString sMediaURL; + bool bHasMediaURL = eDocumentType == DOCUMENT_PPTX + && xShapePropSetInfo->hasPropertyByName(u"MediaURL"_ustr) + && (xShapeProps->getPropertyValue(u"MediaURL"_ustr) >>= sMediaURL); + + if (!xGraphic.is() && !bHasMediaURL) + return false; + } + + return true; +} + ShapeExport& ShapeExport::WriteShape( const Reference< XShape >& xShape ) { if (!xShape) diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx index 24f1de018026..f5d980b6470b 100644 --- a/sc/source/filter/xcl97/xcl97rec.cxx +++ b/sc/source/filter/xcl97/xcl97rec.cxx @@ -1307,10 +1307,10 @@ 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)) + // Return early if unknown/invalid shape; otherwise bogus drawing XML gets written + if (!ShapeExport::IsValidShape(mxShape, drawingml::DOCUMENT_XLSX)) { - SAL_INFO("sc.filter", "unknown shape"); + SAL_INFO("sc.filter", "unknown or invalid/incomplete shape"); return; }
