summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAttila Bakos (NISZ) <bakos.attilakaroly@nisz.hu>2022-01-19 17:43:54 +0100
committerLászló Németh <nemeth@numbertext.org>2022-02-03 09:12:20 +0100
commit4a38ca4035ac03571925e72cb47e0beb8da2003a (patch)
tree6c472f1efe01827320bfd3ae35404f38ee18ba9a
parentb8925251e48534706c6960a54c320d3879317321 (diff)
tdf#146802 OOXML import: fix embedded VML in grouped textbox
E.g. OLE formulas inside them broke document load. Regression from 121cbc250b36290f0f8c7265fea57256dad69553 "tdf#66039 DOCX: import textboxes (with tables, images etc.) in group shapes". Note: now embedded VML OLE is loaded in WPG shapes, thanks to that the ShapeHandler in oox/ has a stack having the start token inside for each shape. Change-Id: I973d78ed88c5c83efffd9629061e2a2c6fdd25e4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128627 Tested-by: László Németh <nemeth@numbertext.org> Reviewed-by: László Németh <nemeth@numbertext.org>
-rw-r--r--include/oox/shape/ShapeContextHandler.hxx18
-rw-r--r--oox/source/shape/ShapeContextHandler.cxx31
-rw-r--r--sw/qa/extras/ooxmlexport/data/tdf146802.docxbin0 -> 72360 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport17.cxx13
-rw-r--r--writerfilter/source/ooxml/OOXMLFastContextHandler.cxx5
5 files changed, 48 insertions, 19 deletions
diff --git a/include/oox/shape/ShapeContextHandler.hxx b/include/oox/shape/ShapeContextHandler.hxx
index 27b70d2cf2c4..a245224730ed 100644
--- a/include/oox/shape/ShapeContextHandler.hxx
+++ b/include/oox/shape/ShapeContextHandler.hxx
@@ -19,6 +19,7 @@
#pragma once
#include <memory>
+#include <stack>
#include <cppuhelper/implbase.hxx>
#include <oox/drawingml/graphicshapecontext.hxx>
#include <oox/core/fragmenthandler2.hxx>
@@ -90,12 +91,15 @@ public:
void setRelationFragmentPath(const OUString & the_value);
sal_Int32 getStartToken() const;
- void setStartToken( sal_Int32 _starttoken );
+ void popStartToken();
+ void pushStartToken( sal_Int32 _starttoken );
void setPosition(const css::awt::Point& rPosition);
- const bool& getFullWPGSupport() { return m_bFullWPGSUpport; };
- void setFullWPGSupport(const bool& rbUse) { m_bFullWPGSUpport = rbUse; };
+ const bool& getFullWPGSupport() { return m_bFullWPGSUpport; }
+ void setFullWPGSupport(const bool& rbUse) { m_bFullWPGSUpport = rbUse; }
+
+ bool isWordProcessingGroupShape() const { return mxWpgContext ? true : false; }
void setDocumentProperties(const css::uno::Reference<css::document::XDocumentProperties>& xDocProps);
void setMediaDescriptor(const css::uno::Sequence<css::beans::PropertyValue>& rMediaDescriptor);
@@ -109,9 +113,13 @@ private:
ShapeContextHandler(ShapeContextHandler const &) = delete;
void operator =(ShapeContextHandler const &) = delete;
- ::sal_uInt32 mnStartToken;
+ // Special stack which always has at least one element.
+ // In case of group shapes with embedded content it will have more element than one.
+ std::stack<sal_uInt32> mnStartTokenStack;
+
css::awt::Point maPosition;
- bool m_bFullWPGSUpport;
+ bool m_bFullWPGSUpport; // Is this DrawingML shape supposed to be proccessed as WPG?
+
drawingml::ShapePtr mpShape;
std::shared_ptr< vml::Drawing > mpDrawing;
diff --git a/oox/source/shape/ShapeContextHandler.cxx b/oox/source/shape/ShapeContextHandler.cxx
index 6eb9e5ce9083..cacd46d82d14 100644
--- a/oox/source/shape/ShapeContextHandler.cxx
+++ b/oox/source/shape/ShapeContextHandler.cxx
@@ -44,7 +44,6 @@ using namespace core;
using namespace drawingml;
ShapeContextHandler::ShapeContextHandler(const rtl::Reference<ShapeFilterBase>& xFilterBase) :
- mnStartToken(0),
m_bFullWPGSUpport(false),
mxShapeFilterBase(xFilterBase)
@@ -225,8 +224,9 @@ uno::Reference<xml::sax::XFastContextHandler>
ShapeContextHandler::getContextHandler(sal_Int32 nElement)
{
uno::Reference<xml::sax::XFastContextHandler> xResult;
+ const sal_uInt32 nStartToken = getStartToken();
- switch (getNamespace( mnStartToken ))
+ switch (getNamespace( nStartToken ))
{
case NMSP_doc:
case NMSP_vml:
@@ -236,19 +236,19 @@ ShapeContextHandler::getContextHandler(sal_Int32 nElement)
xResult.set(getDiagramShapeContext());
break;
case NMSP_dmlLockedCanvas:
- xResult.set(getLockedCanvasContext(mnStartToken));
+ xResult.set(getLockedCanvasContext(nStartToken));
break;
case NMSP_dmlChart:
- xResult.set(getChartShapeContext(mnStartToken));
+ xResult.set(getChartShapeContext(nStartToken));
break;
case NMSP_wps:
- xResult.set(getWpsContext(mnStartToken, nElement));
+ xResult.set(getWpsContext(nStartToken, nElement));
break;
case NMSP_wpg:
- xResult.set(getWpgContext(mnStartToken));
+ xResult.set(getWpgContext(nStartToken));
break;
default:
- xResult.set(getGraphicShapeContext(mnStartToken));
+ xResult.set(getGraphicShapeContext(nStartToken));
break;
}
@@ -456,7 +456,7 @@ ShapeContextHandler::getShape()
//NMSP_dmlChart == getNamespace( mnStartToken ) check is introduced to make sure that
//mnStartToken is set as NMSP_dmlChart in setStartToken.
//Only in case it is set then only the below block of code for ChartShapeContext should be executed.
- else if (mxChartShapeContext.is() && (NMSP_dmlChart == getNamespace( mnStartToken )))
+ else if (mxChartShapeContext.is() && (NMSP_dmlChart == getNamespace( getStartToken() )))
{
ChartGraphicDataContext* pChartGraphicDataContext = dynamic_cast<ChartGraphicDataContext*>(mxChartShapeContext.get());
if (pChartGraphicDataContext)
@@ -514,6 +514,8 @@ ShapeContextHandler::getShape()
}
}
+ if (xResult)
+ popStartToken();
return xResult;
}
@@ -537,12 +539,19 @@ void ShapeContextHandler::setRelationFragmentPath(const OUString & the_value)
sal_Int32 ShapeContextHandler::getStartToken() const
{
- return mnStartToken;
+ assert(mnStartTokenStack.size() && "This stack must not be empty!");
+ return mnStartTokenStack.top();
}
-void ShapeContextHandler::setStartToken( sal_Int32 _starttoken )
+void ShapeContextHandler::popStartToken()
{
- mnStartToken = _starttoken;
+ if (mnStartTokenStack.size() > 1)
+ mnStartTokenStack.pop();
+}
+
+void ShapeContextHandler::pushStartToken( sal_Int32 _starttoken )
+{
+ mnStartTokenStack.push(_starttoken);
}
void ShapeContextHandler::setPosition(const awt::Point& rPosition)
diff --git a/sw/qa/extras/ooxmlexport/data/tdf146802.docx b/sw/qa/extras/ooxmlexport/data/tdf146802.docx
new file mode 100644
index 000000000000..80d2ee17a0bc
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf146802.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
index 6feb92b15149..ee7b37dfc151 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
@@ -51,6 +51,19 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf135906)
// just test round-tripping. The document was exported as corrupt and didn't re-load.
}
+CPPUNIT_TEST_FIXTURE(Test, TestTdf146802)
+{
+ load(DATA_DIRECTORY, "tdf146802.docx");
+
+ // First check if the load failed, as before the fix.
+ CPPUNIT_ASSERT(mxComponent);
+
+ // There is a group shape with text box inside having an embedded VML formula,
+ // check if something missing.
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Where is the formula?", 2, getShapes());
+ // Before the fix the bugdoc failed to load or the formula was missing.
+}
+
CPPUNIT_TEST_FIXTURE(Test, testParaStyleNumLevel)
{
loadAndSave("para-style-num-level.docx");
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
index e245e37b4772..aa9de6408202 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
@@ -1721,7 +1721,7 @@ void OOXMLFastContextHandlerShape::setToken(Token_t nToken)
OOXMLFastContextHandler::setToken(nToken);
if (mrShapeContext.is())
- mrShapeContext->setStartToken(nToken);
+ mrShapeContext->pushStartToken(nToken);
}
void OOXMLFastContextHandlerShape::sendShape( Token_t Element )
@@ -1761,8 +1761,7 @@ void OOXMLFastContextHandlerShape::sendShape( Token_t Element )
bool OOXMLFastContextHandlerShape::isDMLGroupShape() const
{
- return (mrShapeContext->getFullWPGSupport() &&
- (mrShapeContext->getStartToken() == Token_t(oox::NMSP_wpg | oox::XML_wgp)));
+ return (mrShapeContext->getFullWPGSupport() && mrShapeContext->isWordProcessingGroupShape());
};
void OOXMLFastContextHandlerShape::lcl_endFastElement