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

New commits:
commit 2872e5dc20212695b86085e083fec891f4a997d1
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 09:55:31 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
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167885
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>

diff --git a/writerfilter/qa/cppunittests/ooxml/data/recursive_header_rels.docx 
b/writerfilter/qa/cppunittests/ooxml/data/recursive_header_rels.docx
new file mode 100644
index 000000000000..8000760017ed
Binary files /dev/null and 
b/writerfilter/qa/cppunittests/ooxml/data/recursive_header_rels.docx differ
diff --git a/writerfilter/qa/cppunittests/ooxml/ooxml.cxx 
b/writerfilter/qa/cppunittests/ooxml/ooxml.cxx
index 32133df9ba7e..42c8d2222607 100644
--- a/writerfilter/qa/cppunittests/ooxml/ooxml.cxx
+++ b/writerfilter/qa/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/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx 
b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
index c576aa330d46..933812275fda 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
+++ b/writerfilter/source/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/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx 
b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
index 1983ed2583a5..3cf39ba7663c 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
+++ b/writerfilter/source/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