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?