From bc0ca1ec9b157ab8773c9043725c7422f7c1a57c Mon Sep 17 00:00:00 2001 From: Ryan Harrison Date: Thu, 31 Aug 2017 11:57:14 -0400 Subject: 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 Commit-Queue: Ryan Harrison --- core/fpdfapi/page/cpdf_form.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'core/fpdfapi/page/cpdf_form.cpp') diff --git a/core/fpdfapi/page/cpdf_form.cpp b/core/fpdfapi/page/cpdf_form.cpp index c5d9cbffcf..12403a4cc9 100644 --- a/core/fpdfapi/page/cpdf_form.cpp +++ b/core/fpdfapi/page/cpdf_form.cpp @@ -35,23 +35,29 @@ CPDF_Form::~CPDF_Form() {} void CPDF_Form::StartParse(CPDF_AllStates* pGraphicStates, const CFX_Matrix* pParentMatrix, CPDF_Type3Char* pType3Char, - int level) { + std::set* parsedSet) { if (m_ParseState == CONTENT_PARSED || m_ParseState == CONTENT_PARSING) return; + if (!parsedSet) { + if (!m_ParsedSet) + m_ParsedSet = pdfium::MakeUnique>(); + parsedSet = m_ParsedSet.get(); + } + m_pParser = pdfium::MakeUnique(); - m_pParser->Start(this, pGraphicStates, pParentMatrix, pType3Char, level); + m_pParser->Start(this, pGraphicStates, pParentMatrix, pType3Char, parsedSet); m_ParseState = CONTENT_PARSING; } void CPDF_Form::ParseContent() { - ParseContentWithParams(nullptr, nullptr, nullptr, 0); + ParseContentWithParams(nullptr, nullptr, nullptr, nullptr); } void CPDF_Form::ParseContentWithParams(CPDF_AllStates* pGraphicStates, const CFX_Matrix* pParentMatrix, CPDF_Type3Char* pType3Char, - int level) { - StartParse(pGraphicStates, pParentMatrix, pType3Char, level); + std::set* parsedSet) { + StartParse(pGraphicStates, pParentMatrix, pType3Char, parsedSet); ContinueParse(nullptr); } -- cgit v1.2.3