From 9d3fb11a985a8f2aefbf361c0030c7bce2248b8e Mon Sep 17 00:00:00 2001 From: Henrique Nakashima Date: Mon, 4 Jun 2018 19:30:07 +0000 Subject: Do not merge content streams to parse them. Removed the PrepareContent() step in CPDF_ContentParser, as its goal was to merge these streams. In Parse(), now loop through the m_StreamArray and parse each stream separately. Bug: pdfium:1051 Change-Id: Id07f3efe766828081c8cf8601bf69c4f37e20e13 Reviewed-on: https://pdfium-review.googlesource.com/33595 Commit-Queue: Henrique Nakashima Reviewed-by: Ryan Harrison --- core/fpdfapi/page/cpdf_contentparser.cpp | 70 +++++++++++--------------------- core/fpdfapi/page/cpdf_contentparser.h | 6 +-- 2 files changed, 24 insertions(+), 52 deletions(-) diff --git a/core/fpdfapi/page/cpdf_contentparser.cpp b/core/fpdfapi/page/cpdf_contentparser.cpp index ec39858552..9e8f70ef18 100644 --- a/core/fpdfapi/page/cpdf_contentparser.cpp +++ b/core/fpdfapi/page/cpdf_contentparser.cpp @@ -16,7 +16,6 @@ #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_stream.h" #include "core/fpdfapi/parser/cpdf_stream_acc.h" -#include "core/fxcrt/fx_safe_types.h" #include "core/fxcrt/pauseindicator_iface.h" #include "third_party/base/ptr_util.h" @@ -37,9 +36,11 @@ CPDF_ContentParser::CPDF_ContentParser(CPDF_Page* pPage) CPDF_Stream* pStream = pContent->AsStream(); if (pStream) { - m_pSingleStream = pdfium::MakeRetain(pStream); - m_pSingleStream->LoadAllDataFiltered(); - m_CurrentStage = Stage::kPrepareContent; + RetainPtr pSingleStream = + pdfium::MakeRetain(pStream); + pSingleStream->LoadAllDataFiltered(); + m_StreamArray.push_back(pSingleStream); + m_CurrentStage = Stage::kParse; return; } @@ -104,11 +105,10 @@ CPDF_ContentParser::CPDF_ContentParser(CPDF_Form* pForm, pState->SetFillAlpha(1.0f); pState->SetSoftMask(nullptr); } - m_pSingleStream = + RetainPtr pSingleStream = pdfium::MakeRetain(pForm->m_pFormStream.Get()); - m_pSingleStream->LoadAllDataFiltered(); - m_pData.Reset(m_pSingleStream->GetData()); - m_Size = m_pSingleStream->GetSize(); + pSingleStream->LoadAllDataFiltered(); + m_StreamArray.push_back(pSingleStream); } CPDF_ContentParser::~CPDF_ContentParser() {} @@ -123,9 +123,6 @@ bool CPDF_ContentParser::Continue(PauseIndicatorIface* pPause) { return true; } - if (m_CurrentStage == Stage::kPrepareContent) - m_CurrentStage = PrepareContent(); - while (m_CurrentStage == Stage::kParse) { m_CurrentStage = Parse(); if (pPause && pPause->NeedToPauseNow()) @@ -149,40 +146,12 @@ CPDF_ContentParser::Stage CPDF_ContentParser::GetContent() { m_StreamArray[m_CurrentOffset]->LoadAllDataFiltered(); m_CurrentOffset++; - return m_CurrentOffset == m_nStreams ? Stage::kPrepareContent - : Stage::kGetContent; -} - -CPDF_ContentParser::Stage CPDF_ContentParser::PrepareContent() { - m_CurrentOffset = 0; - - if (m_StreamArray.empty()) { - m_pData.Reset(m_pSingleStream->GetData()); - m_Size = m_pSingleStream->GetSize(); + if (m_CurrentOffset >= m_nStreams) { + m_CurrentOffset = 0; return Stage::kParse; } - FX_SAFE_UINT32 safeSize = 0; - for (const auto& stream : m_StreamArray) { - safeSize += stream->GetSize(); - safeSize += 1; - } - if (!safeSize.IsValid()) - return Stage::kComplete; - - m_Size = safeSize.ValueOrDie(); - m_pData.Reset( - std::unique_ptr(FX_Alloc(uint8_t, m_Size))); - - uint32_t pos = 0; - for (const auto& stream : m_StreamArray) { - memcpy(m_pData.Get() + pos, stream->GetData(), stream->GetSize()); - pos += stream->GetSize(); - m_pData.Get()[pos++] = ' '; - } - m_StreamArray.clear(); - - return Stage::kParse; + return Stage::kGetContent; } CPDF_ContentParser::Stage CPDF_ContentParser::Parse() { @@ -195,12 +164,19 @@ CPDF_ContentParser::Stage CPDF_ContentParser::Parse() { nullptr, m_parsedSet.get()); m_pParser->GetCurStates()->m_ColorState.SetDefault(); } - if (m_CurrentOffset >= m_Size) - return Stage::kCheckClip; - m_CurrentOffset += - m_pParser->Parse(m_pData.Get() + m_CurrentOffset, - m_Size - m_CurrentOffset, PARSE_STEP_LIMIT); + m_CurrentOffset += m_pParser->Parse( + m_StreamArray[m_CurrentStream]->GetData() + m_CurrentOffset, + m_StreamArray[m_CurrentStream]->GetSize() - m_CurrentOffset, + PARSE_STEP_LIMIT); + + if (m_CurrentOffset >= m_StreamArray[m_CurrentStream]->GetSize()) { + m_CurrentOffset = 0; + ++m_CurrentStream; + if (m_CurrentStream >= m_nStreams) + return Stage::kCheckClip; + } + return Stage::kParse; } diff --git a/core/fpdfapi/page/cpdf_contentparser.h b/core/fpdfapi/page/cpdf_contentparser.h index f9b491defa..92a3e06890 100644 --- a/core/fpdfapi/page/cpdf_contentparser.h +++ b/core/fpdfapi/page/cpdf_contentparser.h @@ -42,26 +42,22 @@ class CPDF_ContentParser { private: enum class Stage : uint8_t { kGetContent = 1, - kPrepareContent, kParse, kCheckClip, kComplete, }; Stage GetContent(); - Stage PrepareContent(); Stage Parse(); Stage CheckClip(); Stage m_CurrentStage; UnownedPtr const m_pObjectHolder; UnownedPtr m_pType3Char; // Only used when parsing forms. - RetainPtr m_pSingleStream; std::vector> m_StreamArray; - MaybeOwned m_pData; uint32_t m_nStreams = 0; - uint32_t m_Size = 0; uint32_t m_CurrentOffset = 0; + uint32_t m_CurrentStream = 0; // Only used when parsing pages. std::unique_ptr> m_parsedSet; -- cgit v1.2.3