diff options
author | Caolán McNamara <caolanm@redhat.com> | 2018-08-01 12:04:30 +0100 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2018-08-08 13:07:20 +0200 |
commit | 6c6a576d88c287abc1c678fdc30926ac8571237b (patch) | |
tree | 3edf689308e6b4dc415492ac02ef441a33469585 | |
parent | 0ad2f3c452159df6a4d106a571534c4db69a6506 (diff) |
forcepoint#65 pdf page visiting revisits itself
Change-Id: I6d9eb75f0850a94814fb4d69ea1442b826674496
Reviewed-on: https://gerrit.libreoffice.org/58418
Tested-by: Jenkins
Reviewed-by: Michael Stahl <Michael.Stahl@cib.de>
(cherry picked from commit e6d5ef741c75895ed97801112823b8332557d79a)
(cherry picked from commit d63463b0001cc6a439840d0cee36b6678aea467e)
-rw-r--r-- | include/vcl/filter/pdfdocument.hxx | 4 | ||||
-rw-r--r-- | vcl/source/filter/ipdf/pdfdocument.cxx | 20 |
2 files changed, 20 insertions, 4 deletions
diff --git a/include/vcl/filter/pdfdocument.hxx b/include/vcl/filter/pdfdocument.hxx index 5011504f13df..48240b7ecb98 100644 --- a/include/vcl/filter/pdfdocument.hxx +++ b/include/vcl/filter/pdfdocument.hxx @@ -49,6 +49,7 @@ class VCL_DLLPUBLIC PDFObjectElement : public PDFElement PDFDocument& m_rDoc; double m_fObjectValue; double m_fGenerationValue; + bool m_bVisiting; std::map<OString, PDFElement*> m_aDictionary; /// If set, the object contains this number element (outside any dictionary/array). PDFNumberElement* m_pNumberElement; @@ -108,6 +109,9 @@ public: SvMemoryStream* GetStreamBuffer() const; void SetStreamBuffer(std::unique_ptr<SvMemoryStream>& pStreamBuffer); PDFDocument& GetDocument(); + + /// Visits the page tree recursively, looking for page objects. + void visitPages(std::vector<PDFObjectElement*>& rRet); }; /// Array object: a list. diff --git a/vcl/source/filter/ipdf/pdfdocument.cxx b/vcl/source/filter/ipdf/pdfdocument.cxx index b2c3a8577469..20a2b951ab6c 100644 --- a/vcl/source/filter/ipdf/pdfdocument.cxx +++ b/vcl/source/filter/ipdf/pdfdocument.cxx @@ -1769,15 +1769,17 @@ const std::vector< std::unique_ptr<PDFElement> >& PDFDocument::GetElements() } /// Visits the page tree recursively, looking for page objects. -static void visitPages(PDFObjectElement* pPages, std::vector<PDFObjectElement*>& rRet) +void PDFObjectElement::visitPages(std::vector<PDFObjectElement*>& rRet) { - auto pKids = dynamic_cast<PDFArrayElement*>(pPages->Lookup("Kids")); + auto pKids = dynamic_cast<PDFArrayElement*>(Lookup("Kids")); if (!pKids) { SAL_WARN("vcl.filter", "visitPages: pages has no kids"); return; } + m_bVisiting = true; + for (const auto& pKid : pKids->GetElements()) { auto pReference = dynamic_cast<PDFReferenceElement*>(pKid); @@ -1788,14 +1790,23 @@ static void visitPages(PDFObjectElement* pPages, std::vector<PDFObjectElement*>& if (!pKidObject) continue; + // detect if visiting reenters itself + if (pKidObject->m_bVisiting) + { + SAL_WARN("vcl.filter", "visitPages: loop in hierarchy"); + continue; + } + auto pName = dynamic_cast<PDFNameElement*>(pKidObject->Lookup("Type")); if (pName && pName->GetValue() == "Pages") // Pages inside pages: recurse. - visitPages(pKidObject, rRet); + pKidObject->visitPages(rRet); else // Found an actual page. rRet.push_back(pKidObject); } + + m_bVisiting = false; } std::vector<PDFObjectElement*> PDFDocument::GetPages() @@ -1840,7 +1851,7 @@ std::vector<PDFObjectElement*> PDFDocument::GetPages() return aRet; } - visitPages(pPages, aRet); + pPages->visitPages(aRet); return aRet; } @@ -2138,6 +2149,7 @@ PDFObjectElement::PDFObjectElement(PDFDocument& rDoc, double fObjectValue, doubl : m_rDoc(rDoc), m_fObjectValue(fObjectValue), m_fGenerationValue(fGenerationValue), + m_bVisiting(false), m_pNumberElement(nullptr), m_nDictionaryOffset(0), m_nDictionaryLength(0), |