diff options
-rw-r--r-- | include/xmloff/txtparae.hxx | 5 | ||||
-rw-r--r-- | xmloff/source/text/txtparae.cxx | 33 |
2 files changed, 33 insertions, 5 deletions
diff --git a/include/xmloff/txtparae.hxx b/include/xmloff/txtparae.hxx index 36d554be2a20..1ba8b0b1a0c8 100644 --- a/include/xmloff/txtparae.hxx +++ b/include/xmloff/txtparae.hxx @@ -30,6 +30,7 @@ #include <xmloff/xmltoken.hxx> #include <xmloff/SinglePropertySetInfoCache.hxx> #include <xmloff/XMLTextListAutoStylePool.hxx> +#include <o3tl/sorted_vector.hxx> #include <o3tl/span.hxx> #include <memory> #include <vector> @@ -51,6 +52,7 @@ namespace com::sun::star namespace beans { class XPropertySet; class XPropertyState; class XPropertySetInfo; } namespace container { class XEnumeration; class XIndexAccess; class XNameReplace; } + namespace drawing { class XShape; } namespace text { class XTextContent; class XTextRange; class XText; class XFootnote; class XTextFrame; class XTextSection; class XTextField; } @@ -110,6 +112,9 @@ class XMLOFF_DLLPUBLIC XMLTextParagraphExport : public XMLStyleExport XMLTextListsHelper* mpTextListsHelper; ::std::vector< std::unique_ptr<XMLTextListsHelper> > maTextListsHelperStack; + o3tl::sorted_vector<css::uno::Reference<css::text::XTextFrame>> maFrameRecurseGuard; + o3tl::sorted_vector<css::uno::Reference<css::drawing::XShape>> maShapeRecurseGuard; + bool mbCollected; enum class FrameType { Text, Graphic, Embedded, Shape }; diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx index aaf47ddd4b71..1e02dbce341d 100644 --- a/xmloff/source/text/txtparae.cxx +++ b/xmloff/source/text/txtparae.cxx @@ -110,6 +110,7 @@ #include <iterator> #include <officecfg/Office/Common.hxx> #include <o3tl/safeint.hxx> +#include <comphelper/scopeguard.hxx> #include <comphelper/sequenceashashmap.hxx> using namespace ::com::sun::star; @@ -3054,17 +3055,39 @@ void XMLTextParagraphExport::exportAnyTextFrame( if ( bExportContent ) { Reference < XTextFrame > xTxtFrame( rTxtCntnt, UNO_QUERY ); - Reference < XText > xTxt(xTxtFrame->getText()); - exportFrameFrames( true, bIsProgress, xTxtFrame ); - exportText( xTxt, bAutoStyles, bIsProgress, true ); + bool bAlreadySeen = !maFrameRecurseGuard.insert(xTxtFrame).second; + if (bAlreadySeen) + { + SAL_WARN("xmloff", "loop in frame export, ditching"); + } + else + { + comphelper::ScopeGuard const g([this, xTxtFrame]() { + maFrameRecurseGuard.erase(xTxtFrame); + }); + Reference < XText > xTxt(xTxtFrame->getText()); + exportFrameFrames( true, bIsProgress, xTxtFrame ); + exportText( xTxt, bAutoStyles, bIsProgress, true ); + } } } break; case FrameType::Shape: { Reference < XShape > xShape( rTxtCntnt, UNO_QUERY ); - css::uno::Sequence<OUString> aAutoStylePropNames = GetAutoStylePool().GetPropertyNames(); - GetExport().GetShapeExport()->collectShapeAutoStyles( xShape, aAutoStylePropNames ); + bool bAlreadySeen = !maShapeRecurseGuard.insert(xShape).second; + if (bAlreadySeen) + { + SAL_WARN("xmloff", "loop in shape export, ditching"); + } + else + { + comphelper::ScopeGuard const g([this, xShape]() { + maShapeRecurseGuard.erase(xShape); + }); + css::uno::Sequence<OUString> aAutoStylePropNames = GetAutoStylePool().GetPropertyNames(); + GetExport().GetShapeExport()->collectShapeAutoStyles( xShape, aAutoStylePropNames ); + } } break; default: |