summaryrefslogtreecommitdiff
path: root/core/fpdfapi/page/cpdf_streamcontentparser.cpp
diff options
context:
space:
mode:
authorRyan Harrison <rharrison@chromium.org>2017-08-31 11:57:14 -0400
committerChromium commit bot <commit-bot@chromium.org>2017-08-31 17:06:29 +0000
commitbc0ca1ec9b157ab8773c9043725c7422f7c1a57c (patch)
treec1e46db02a10e3377d597265dcf125b980c277b0 /core/fpdfapi/page/cpdf_streamcontentparser.cpp
parentdf064df7a08e008b3c8e4d56bb0b75da9f014147 (diff)
downloadpdfium-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.cpp13
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);