summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2018-08-01 12:04:30 +0100
committerAndras Timar <andras.timar@collabora.com>2018-08-08 13:07:20 +0200
commit6c6a576d88c287abc1c678fdc30926ac8571237b (patch)
tree3edf689308e6b4dc415492ac02ef441a33469585
parent0ad2f3c452159df6a4d106a571534c4db69a6506 (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.hxx4
-rw-r--r--vcl/source/filter/ipdf/pdfdocument.cxx20
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),