diff options
author | Henrique Nakashima <hnakashima@chromium.org> | 2018-04-11 00:13:36 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2018-04-11 00:13:36 +0000 |
commit | 6bebd2e3cfb7790580722836d0debab3103c94d0 (patch) | |
tree | cb8096e419b61d4b6aa6214ac7779f672d0761d9 /core/fpdfapi/page/cpdf_function.cpp | |
parent | 486f39568b6f336b4e6c81300ee9caae54ebdff2 (diff) | |
download | pdfium-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.cpp | 18 |
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); |