diff options
author | Caolán McNamara <caolanm@redhat.com> | 2018-08-01 15:05:45 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2018-08-01 21:48:20 +0200 |
commit | 84aa79f52c7d49f326d38d1782a9b91f57c78cff (patch) | |
tree | 616375cc47584502eb62aca77ea913195b9901aa /vcl | |
parent | d1ea4db02dac313a9836b26f05f00e9a34b25600 (diff) |
forcepoint#66 protect against infinite parse recurse
Change-Id: I0313cc141469a00b7d6a5bd15400e9d5a8f686cf
Reviewed-on: https://gerrit.libreoffice.org/58440
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/source/filter/ipdf/pdfdocument.cxx | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/vcl/source/filter/ipdf/pdfdocument.cxx b/vcl/source/filter/ipdf/pdfdocument.cxx index 7d4efc9e0eb0..3d9008a22943 100644 --- a/vcl/source/filter/ipdf/pdfdocument.cxx +++ b/vcl/source/filter/ipdf/pdfdocument.cxx @@ -1815,16 +1815,16 @@ size_t PDFDocument::GetObjectOffset(size_t nIndex) const const std::vector<std::unique_ptr<PDFElement>>& PDFDocument::GetElements() { return m_aElements; } /// Visits the page tree recursively, looking for page objects. -void PDFObjectElement::visitPages(std::vector<PDFObjectElement*>& rRet) +static void visitPages(PDFObjectElement* pPages, std::vector<PDFObjectElement*>& rRet) { - auto pKids = dynamic_cast<PDFArrayElement*>(Lookup("Kids")); + auto pKids = dynamic_cast<PDFArrayElement*>(pPages->Lookup("Kids")); if (!pKids) { SAL_WARN("vcl.filter", "visitPages: pages has no kids"); return; } - m_bVisiting = true; + pPages->setVisiting(true); for (const auto& pKid : pKids->GetElements()) { @@ -1837,7 +1837,7 @@ void PDFObjectElement::visitPages(std::vector<PDFObjectElement*>& rRet) continue; // detect if visiting reenters itself - if (pKidObject->m_bVisiting) + if (pKidObject->alreadyVisiting()) { SAL_WARN("vcl.filter", "visitPages: loop in hierarchy"); continue; @@ -1846,13 +1846,13 @@ void PDFObjectElement::visitPages(std::vector<PDFObjectElement*>& rRet) auto pName = dynamic_cast<PDFNameElement*>(pKidObject->Lookup("Type")); if (pName && pName->GetValue() == "Pages") // Pages inside pages: recurse. - pKidObject->visitPages(rRet); + visitPages(pKidObject, rRet); else // Found an actual page. rRet.push_back(pKidObject); } - m_bVisiting = false; + pPages->setVisiting(false); } std::vector<PDFObjectElement*> PDFDocument::GetPages() @@ -1897,7 +1897,7 @@ std::vector<PDFObjectElement*> PDFDocument::GetPages() return aRet; } - pPages->visitPages(aRet); + visitPages(pPages, aRet); return aRet; } @@ -2133,7 +2133,6 @@ 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) @@ -2163,6 +2162,8 @@ size_t PDFDictionaryElement::Parse(const std::vector<std::unique_ptr<PDFElement> if (!rDictionary.empty()) return nRet; + pThis->setParsing(true); + auto pThisObject = dynamic_cast<PDFObjectElement*>(pThis); // This is set to non-nullptr here for nested dictionaries only. auto pThisDictionary = dynamic_cast<PDFDictionaryElement*>(pThis); @@ -2208,7 +2209,7 @@ size_t PDFDictionaryElement::Parse(const std::vector<std::unique_ptr<PDFElement> pThisObject->SetDictionaryOffset(nDictionaryOffset); } } - else + else if (!pDictionary->alreadyParsing()) { // Nested dictionary. i = PDFDictionaryElement::Parse(rElements, pDictionary, pDictionary->m_aItems); @@ -2386,6 +2387,8 @@ size_t PDFDictionaryElement::Parse(const std::vector<std::unique_ptr<PDFElement> aNumbers.clear(); } + pThis->setParsing(false); + return nRet; } |