summaryrefslogtreecommitdiff
path: root/core/fpdfapi/page/cpdf_function.cpp
diff options
context:
space:
mode:
authorHenrique Nakashima <hnakashima@chromium.org>2018-04-11 00:13:36 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-04-11 00:13:36 +0000
commit6bebd2e3cfb7790580722836d0debab3103c94d0 (patch)
treecb8096e419b61d4b6aa6214ac7779f672d0761d9 /core/fpdfapi/page/cpdf_function.cpp
parent486f39568b6f336b4e6c81300ee9caae54ebdff2 (diff)
downloadpdfium-6bebd2e3cfb7790580722836d0debab3103c94d0.tar.xz
Avoid stack overflow when loading CPDF_Function.chromium/3395
CPDF_StitchFuncs that reference each other create a Load() loop. Maintaining a set of the visited CPDF_Objects during a Load() call tree prevents that. Bug: chromium:830221 Change-Id: I6f494da16c6d79f05870ff85cff38ff8fe69ecfe Reviewed-on: https://pdfium-review.googlesource.com/30050 Commit-Queue: dsinclair <dsinclair@chromium.org> Reviewed-by: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'core/fpdfapi/page/cpdf_function.cpp')
-rw-r--r--core/fpdfapi/page/cpdf_function.cpp18
1 files changed, 15 insertions, 3 deletions
diff --git a/core/fpdfapi/page/cpdf_function.cpp b/core/fpdfapi/page/cpdf_function.cpp
index 635c53a95f..3e99eb8176 100644
--- a/core/fpdfapi/page/cpdf_function.cpp
+++ b/core/fpdfapi/page/cpdf_function.cpp
@@ -17,10 +17,22 @@
// static
std::unique_ptr<CPDF_Function> CPDF_Function::Load(CPDF_Object* pFuncObj) {
+ std::set<CPDF_Object*> visited;
+ return Load(pFuncObj, &visited);
+}
+
+// static
+std::unique_ptr<CPDF_Function> CPDF_Function::Load(
+ CPDF_Object* pFuncObj,
+ std::set<CPDF_Object*>* pVisited) {
std::unique_ptr<CPDF_Function> pFunc;
if (!pFuncObj)
return pFunc;
+ if (pdfium::ContainsKey(*pVisited, pFuncObj))
+ return nullptr;
+ pdfium::ScopedSetInsertion<CPDF_Object*> insertion(pVisited, pFuncObj);
+
int iType = -1;
if (CPDF_Stream* pStream = pFuncObj->AsStream())
iType = pStream->GetDict()->GetIntegerFor("FunctionType");
@@ -37,7 +49,7 @@ std::unique_ptr<CPDF_Function> CPDF_Function::Load(CPDF_Object* pFuncObj) {
else if (type == Type::kType4PostScript)
pFunc = pdfium::MakeUnique<CPDF_PSFunc>();
- if (!pFunc || !pFunc->Init(pFuncObj))
+ if (!pFunc || !pFunc->Init(pFuncObj, pVisited))
return nullptr;
return pFunc;
@@ -64,7 +76,7 @@ CPDF_Function::~CPDF_Function() {
FX_Free(m_pRanges);
}
-bool CPDF_Function::Init(CPDF_Object* pObj) {
+bool CPDF_Function::Init(CPDF_Object* pObj, std::set<CPDF_Object*>* pVisited) {
CPDF_Stream* pStream = pObj->AsStream();
CPDF_Dictionary* pDict = pStream ? pStream->GetDict() : pObj->AsDictionary();
@@ -89,7 +101,7 @@ bool CPDF_Function::Init(CPDF_Object* pObj) {
m_pRanges[i] = pRanges->GetFloatAt(i);
}
uint32_t old_outputs = m_nOutputs;
- if (!v_Init(pObj))
+ if (!v_Init(pObj, pVisited))
return false;
if (m_pRanges && m_nOutputs > old_outputs) {
m_pRanges = FX_Realloc(float, m_pRanges, m_nOutputs * 2);