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 1562265ced2aad987d7e7734cd9c0f7263dd357c
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 14:02:29 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/+/167886
    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 8602ecd8e77d..532ff4e9d2e1 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:
+    loadFromURL(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 8e0cd9aa8a86..368b8d07465a 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
@@ -764,8 +764,9 @@ void OOXMLDocumentImpl::resolveEmbeddingsStream(const 
OOXMLStream::Pointer_t& pS
                 {
                     importSubStreamRelations(pStream, OOXMLStream::CHARTS);
                 }
-                if(bHeaderFooterFound)
+                if (bHeaderFooterFound && maSeenStreams.find(customTarget) == 
maSeenStreams.end())
                 {
+                    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 3f57696b2d25..917ffffea002 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> aEmbeddings;
+    std::set<OUString> maSeenStreams;
     bool mbIsSubstream;
     bool mbSkipImages;
     /// How many paragraphs equal to 1 percent?

Reply via email to