sw/qa/writerfilter/cppunittests/ooxml/data/recursive_header_rels.docx |binary
 sw/qa/writerfilter/cppunittests/ooxml/ooxml.cxx                       |    7 
+++++++
 sw/source/writerfilter/ooxml/OOXMLDocumentImpl.cxx                    |    3 
++-
 sw/source/writerfilter/ooxml/OOXMLDocumentImpl.hxx                    |    2 ++
 4 files changed, 11 insertions(+), 1 deletion(-)

New commits:
commit e39c57022afbe84601f58ef5bae0f12e69d33fc5
Author:     Jaume Pujantell <jaume.pujant...@collabora.com>
AuthorDate: Fri May 17 16:44:12 2024 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue May 21 08:33:10 2024 +0200

    writerfilter: avoid infinit loop when resolving embeddings on docx
    
    If a docx file contains a loop on the .rels files for headers and/or footers
    the code would enter an infinite recursion while looking for embeddings.
    
    Change-Id: I2122fd6b1677812f561e96a9511a61b0e938e94a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167784
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git 
a/sw/qa/writerfilter/cppunittests/ooxml/data/recursive_header_rels.docx 
b/sw/qa/writerfilter/cppunittests/ooxml/data/recursive_header_rels.docx
new file mode 100644
index 000000000000..8000760017ed
Binary files /dev/null and 
b/sw/qa/writerfilter/cppunittests/ooxml/data/recursive_header_rels.docx differ
diff --git a/sw/qa/writerfilter/cppunittests/ooxml/ooxml.cxx 
b/sw/qa/writerfilter/cppunittests/ooxml/ooxml.cxx
index c146560ed352..5cbd9e219449 100644
--- a/sw/qa/writerfilter/cppunittests/ooxml/ooxml.cxx
+++ b/sw/qa/writerfilter/cppunittests/ooxml/ooxml.cxx
@@ -62,6 +62,13 @@ CPPUNIT_TEST_FIXTURE(Test, testFloatingTableLeak)
     CPPUNIT_ASSERT(xParagraph->supportsService("com.sun.star.text.Paragraph"));
     CPPUNIT_ASSERT(!xParaEnum->hasMoreElements());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testRecursiveHeaderRels)
+{
+    // Given a document with self-referencing rels in a header/footer:
+    loadFromFile(u"recursive_header_rels.docx");
+    // It should not crash/hang on load
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/writerfilter/ooxml/OOXMLDocumentImpl.cxx 
b/sw/source/writerfilter/ooxml/OOXMLDocumentImpl.cxx
index 0530969fbccc..0fdf1b927956 100644
--- a/sw/source/writerfilter/ooxml/OOXMLDocumentImpl.cxx
+++ b/sw/source/writerfilter/ooxml/OOXMLDocumentImpl.cxx
@@ -762,8 +762,9 @@ void OOXMLDocumentImpl::resolveEmbeddingsStream(const 
OOXMLStream::Pointer_t& pS
                 {
                     importSubStreamRelations(pStream, OOXMLStream::CHARTS);
                 }
-                if(bHeaderFooterFound)
+                if (bHeaderFooterFound && 
!maSeenStreams.contains(customTarget))
                 {
+                    maSeenStreams.insert(customTarget);
                     try
                     {
                         OOXMLStream::Pointer_t Stream = 
OOXMLDocumentFactory::createStream(pStream, streamType);
diff --git a/sw/source/writerfilter/ooxml/OOXMLDocumentImpl.hxx 
b/sw/source/writerfilter/ooxml/OOXMLDocumentImpl.hxx
index 87aae13ab94f..ee8a01972f93 100644
--- a/sw/source/writerfilter/ooxml/OOXMLDocumentImpl.hxx
+++ b/sw/source/writerfilter/ooxml/OOXMLDocumentImpl.hxx
@@ -30,6 +30,7 @@
 
 #include <vector>
 #include <stack>
+#include <set>
 
 namespace writerfilter::ooxml
 {
@@ -55,6 +56,7 @@ class OOXMLDocumentImpl : public OOXMLDocument
     css::uno::Reference<css::io::XInputStream> mxEmbeddings;
     css::uno::Sequence < css::beans::PropertyValue > mxEmbeddingsList;
     std::vector<css::beans::PropertyValue> m_aEmbeddings;
+    std::set<OUString> maSeenStreams;
     bool mbIsSubstream;
     bool mbSkipImages;
     /// How many paragraphs equal to 1 percent?

Reply via email to