From 7edcf2ce07e87022361a0e00fde27aad738c0621 Mon Sep 17 00:00:00 2001 From: Henrique Nakashima Date: Tue, 5 Jun 2018 19:43:11 +0000 Subject: Revert "Do not merge content streams to parse them." This reverts commit 9d3fb11a985a8f2aefbf361c0030c7bce2248b8e. Reason for revert: Break rendering of http://www.flbb.lu/bio_files/BIO_25_2005.pdf Original change's description: > 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 TBR=thestig@chromium.org,hnakashima@chromium.org,rharrison@chromium.org Change-Id: I8186b2dac8538ca477302bb91e22dcc54124461a Bug: pdfium:1051 Reviewed-on: https://pdfium-review.googlesource.com/33991 Commit-Queue: Henrique Nakashima Reviewed-by: Henrique Nakashima --- core/fpdfapi/page/cpdf_contentparser.cpp | 71 +++++++++++++++++++++----------- core/fpdfapi/page/cpdf_contentparser.h | 6 ++- 2 files changed, 52 insertions(+), 25 deletions(-) diff --git a/core/fpdfapi/page/cpdf_contentparser.cpp b/core/fpdfapi/page/cpdf_contentparser.cpp index 471e707322..29b5f122bd 100644 --- a/core/fpdfapi/page/cpdf_contentparser.cpp +++ b/core/fpdfapi/page/cpdf_contentparser.cpp @@ -16,6 +16,7 @@ #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,11 +38,9 @@ CPDF_ContentParser::CPDF_ContentParser(CPDF_Page* pPage) CPDF_Stream* pStream = pContent->AsStream(); if (pStream) { - RetainPtr pSingleStream = - pdfium::MakeRetain(pStream); - pSingleStream->LoadAllDataFiltered(); - m_StreamArray.push_back(pSingleStream); - m_CurrentStage = Stage::kParse; + m_pSingleStream = pdfium::MakeRetain(pStream); + m_pSingleStream->LoadAllDataFiltered(); + m_CurrentStage = Stage::kPrepareContent; return; } @@ -107,10 +106,10 @@ CPDF_ContentParser::CPDF_ContentParser(CPDF_Form* pForm, pState->SetFillAlpha(1.0f); pState->SetSoftMask(nullptr); } - RetainPtr pSingleStream = - pdfium::MakeRetain(pForm->GetStream()); - pSingleStream->LoadAllDataFiltered(); - m_StreamArray.push_back(pSingleStream); + m_pSingleStream = pdfium::MakeRetain(pForm->GetStream()); + m_pSingleStream->LoadAllDataFiltered(); + m_pData.Reset(m_pSingleStream->GetData()); + m_Size = m_pSingleStream->GetSize(); } CPDF_ContentParser::~CPDF_ContentParser() {} @@ -125,6 +124,9 @@ 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()) @@ -148,12 +150,40 @@ CPDF_ContentParser::Stage CPDF_ContentParser::GetContent() { m_StreamArray[m_CurrentOffset]->LoadAllDataFiltered(); m_CurrentOffset++; - if (m_CurrentOffset >= m_nStreams) { - m_CurrentOffset = 0; + 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(); return Stage::kParse; } - return Stage::kGetContent; + 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; } CPDF_ContentParser::Stage CPDF_ContentParser::Parse() { @@ -166,19 +196,12 @@ 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_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; - } - + m_CurrentOffset += + m_pParser->Parse(m_pData.Get() + m_CurrentOffset, + m_Size - m_CurrentOffset, PARSE_STEP_LIMIT); return Stage::kParse; } diff --git a/core/fpdfapi/page/cpdf_contentparser.h b/core/fpdfapi/page/cpdf_contentparser.h index 92a3e06890..f9b491defa 100644 --- a/core/fpdfapi/page/cpdf_contentparser.h +++ b/core/fpdfapi/page/cpdf_contentparser.h @@ -42,22 +42,26 @@ 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