diff options
author | Ryan Harrison <rharrison@chromium.org> | 2017-08-31 11:57:14 -0400 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-08-31 17:06:29 +0000 |
commit | bc0ca1ec9b157ab8773c9043725c7422f7c1a57c (patch) | |
tree | c1e46db02a10e3377d597265dcf125b980c277b0 /core/fpdfapi/page/cpdf_streamcontentparser.cpp | |
parent | df064df7a08e008b3c8e4d56bb0b75da9f014147 (diff) | |
download | pdfium-bc0ca1ec9b157ab8773c9043725c7422f7c1a57c.tar.xz |
Prevent duplicate parses of same data, in the same recursive descent
When parsing if there is a loop in the data being parsed, the
recursions will just keep cycling until it exhausts memory and
crashes. This CL introduces a parsed set, which a reference to is
passed down the descent. If the data being parsed at a specific stage
of the descent is already in the parsed set, then the parse returns at
that point.
BUG=chromium:759224
Change-Id: I1dca73d81020099dec03fd49aaa44cdcdf38e17e
Reviewed-on: https://pdfium-review.googlesource.com/12470
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Diffstat (limited to 'core/fpdfapi/page/cpdf_streamcontentparser.cpp')
-rw-r--r-- | core/fpdfapi/page/cpdf_streamcontentparser.cpp | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp index 7bd6b50123..3755b2985a 100644 --- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp +++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp @@ -37,6 +37,7 @@ #include "core/fxge/cfx_graphstatedata.h" #include "third_party/base/logging.h" #include "third_party/base/ptr_util.h" +#include "third_party/base/stl_util.h" namespace { @@ -243,13 +244,13 @@ CPDF_StreamContentParser::CPDF_StreamContentParser( CPDF_Dictionary* pResources, const CFX_FloatRect& rcBBox, CPDF_AllStates* pStates, - int level) + std::set<const uint8_t*>* parsedSet) : m_pDocument(pDocument), m_pPageResources(pPageResources), m_pParentResources(pParentResources), m_pResources(pResources), m_pObjectHolder(pObjHolder), - m_Level(level), + m_ParsedSet(parsedSet), m_BBox(rcBBox), m_ParamStartPos(0), m_ParamCount(0), @@ -776,7 +777,7 @@ void CPDF_StreamContentParser::AddForm(CPDF_Stream* pStream) { status.m_ColorState = m_pCurStates->m_ColorState; status.m_TextState = m_pCurStates->m_TextState; pFormObj->m_pForm->ParseContentWithParams(&status, nullptr, nullptr, - m_Level + 1); + m_ParsedSet.Get()); if (!m_pObjectHolder->BackgroundAlphaNeeded() && pFormObj->m_pForm->BackgroundAlphaNeeded()) { m_pObjectHolder->SetBackgroundAlphaNeeded(true); @@ -1507,9 +1508,13 @@ void CPDF_StreamContentParser::AddPathObject(int FillType, bool bStroke) { uint32_t CPDF_StreamContentParser::Parse(const uint8_t* pData, uint32_t dwSize, uint32_t max_cost) { - if (m_Level > kMaxFormLevel) + if (m_ParsedSet->size() > kMaxFormLevel || + pdfium::ContainsKey(*m_ParsedSet, pData)) return dwSize; + pdfium::ScopedSetInsertion<const uint8_t*> scopedInsert(m_ParsedSet.Get(), + pData); + uint32_t InitObjCount = m_pObjectHolder->GetPageObjectList()->size(); CPDF_StreamParser syntax(pData, dwSize, m_pDocument->GetByteStringPool()); CPDF_StreamParserAutoClearer auto_clearer(&m_pSyntax, &syntax); |