diff options
author | Henrique Nakashima <hnakashima@chromium.org> | 2018-06-05 19:43:11 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2018-06-05 19:43:11 +0000 |
commit | 7edcf2ce07e87022361a0e00fde27aad738c0621 (patch) | |
tree | 05ea6ea6231744fb191aa36f59cad164e073baee /core | |
parent | 778e59ed40ed31f6176a68253b694acd31f640c9 (diff) | |
download | pdfium-7edcf2ce07e87022361a0e00fde27aad738c0621.tar.xz |
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 <hnakashima@chromium.org>
> Reviewed-by: Ryan Harrison <rharrison@chromium.org>
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 <hnakashima@chromium.org>
Reviewed-by: Henrique Nakashima <hnakashima@chromium.org>
Diffstat (limited to 'core')
-rw-r--r-- | core/fpdfapi/page/cpdf_contentparser.cpp | 71 | ||||
-rw-r--r-- | 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<CPDF_StreamAcc> pSingleStream = - pdfium::MakeRetain<CPDF_StreamAcc>(pStream); - pSingleStream->LoadAllDataFiltered(); - m_StreamArray.push_back(pSingleStream); - m_CurrentStage = Stage::kParse; + m_pSingleStream = pdfium::MakeRetain<CPDF_StreamAcc>(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<CPDF_StreamAcc> pSingleStream = - pdfium::MakeRetain<CPDF_StreamAcc>(pForm->GetStream()); - pSingleStream->LoadAllDataFiltered(); - m_StreamArray.push_back(pSingleStream); + m_pSingleStream = pdfium::MakeRetain<CPDF_StreamAcc>(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<uint8_t, FxFreeDeleter>(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<CPDF_PageObjectHolder> const m_pObjectHolder; UnownedPtr<CPDF_Type3Char> m_pType3Char; // Only used when parsing forms. + RetainPtr<CPDF_StreamAcc> m_pSingleStream; std::vector<RetainPtr<CPDF_StreamAcc>> m_StreamArray; + MaybeOwned<uint8_t, FxFreeDeleter> 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<std::set<const uint8_t*>> m_parsedSet; |