Refactor page content parsing code in CPDF_ContentParser. The page content can be an array or a stream. Make separate functions for array and stream parsing, and for handling failures. Change-Id: I9b725d10228ef046195cb46a9a8becf4de2f5d00 Reviewed-on: https://pdfium-review.googlesource.com/c/39874 Commit-Queue: Lei Zhang <thestig@chromium.org> Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_contentparser.cpp b/core/fpdfapi/page/cpdf_contentparser.cpp index b3b7371..85f1f1a 100644 --- a/core/fpdfapi/page/cpdf_contentparser.cpp +++ b/core/fpdfapi/page/cpdf_contentparser.cpp
@@ -21,8 +21,6 @@ #include "core/fxcrt/pauseindicator_iface.h" #include "third_party/base/ptr_util.h" -#define PARSE_STEP_LIMIT 100 - CPDF_ContentParser::CPDF_ContentParser(CPDF_Page* pPage) : m_CurrentStage(Stage::kGetContent), m_pObjectHolder(pPage) { ASSERT(pPage); @@ -34,30 +32,21 @@ CPDF_Object* pContent = pPage->GetDict()->GetDirectObjectFor(pdfium::page_object::kContents); if (!pContent) { - m_CurrentStage = Stage::kComplete; + HandlePageContentFailure(); return; } CPDF_Stream* pStream = pContent->AsStream(); if (pStream) { - m_pSingleStream = pdfium::MakeRetain<CPDF_StreamAcc>(pStream); - m_pSingleStream->LoadAllDataFiltered(); - m_CurrentStage = Stage::kPrepareContent; + HandlePageContentStream(pStream); return; } CPDF_Array* pArray = pContent->AsArray(); - if (!pArray) { - m_CurrentStage = Stage::kComplete; + if (pArray && HandlePageContentArray(pArray)) return; - } - m_nStreams = pArray->size(); - if (m_nStreams == 0) { - m_CurrentStage = Stage::kComplete; - return; - } - m_StreamArray.resize(m_nStreams); + HandlePageContentFailure(); } CPDF_ContentParser::CPDF_ContentParser(CPDF_Form* pForm, @@ -208,8 +197,9 @@ if (m_StreamSegmentOffsets.empty()) m_StreamSegmentOffsets.push_back(0); + static constexpr uint32_t kParseStepLimit = 100; m_CurrentOffset += m_pParser->Parse(m_pData.Get(), m_Size, m_CurrentOffset, - PARSE_STEP_LIMIT, m_StreamSegmentOffsets); + kParseStepLimit, m_StreamSegmentOffsets); return Stage::kParse; } @@ -239,3 +229,22 @@ } return Stage::kComplete; } + +void CPDF_ContentParser::HandlePageContentStream(CPDF_Stream* pStream) { + m_pSingleStream = pdfium::MakeRetain<CPDF_StreamAcc>(pStream); + m_pSingleStream->LoadAllDataFiltered(); + m_CurrentStage = Stage::kPrepareContent; +} + +bool CPDF_ContentParser::HandlePageContentArray(CPDF_Array* pArray) { + m_nStreams = pArray->size(); + if (m_nStreams == 0) + return false; + + m_StreamArray.resize(m_nStreams); + return true; +} + +void CPDF_ContentParser::HandlePageContentFailure() { + m_CurrentStage = Stage::kComplete; +}
diff --git a/core/fpdfapi/page/cpdf_contentparser.h b/core/fpdfapi/page/cpdf_contentparser.h index 70be98c..c27342e 100644 --- a/core/fpdfapi/page/cpdf_contentparser.h +++ b/core/fpdfapi/page/cpdf_contentparser.h
@@ -17,9 +17,11 @@ #include "core/fxcrt/unowned_ptr.h" class CPDF_AllStates; +class CPDF_Array; class CPDF_Form; class CPDF_Page; class CPDF_PageObjectHolder; +class CPDF_Stream; class CPDF_StreamAcc; class CPDF_Type3Char; @@ -53,6 +55,10 @@ Stage Parse(); Stage CheckClip(); + void HandlePageContentStream(CPDF_Stream* pStream); + bool HandlePageContentArray(CPDF_Array* pArray); + void HandlePageContentFailure(); + Stage m_CurrentStage; UnownedPtr<CPDF_PageObjectHolder> const m_pObjectHolder; UnownedPtr<CPDF_Type3Char> m_pType3Char; // Only used when parsing forms.