From 81981300c2892598784f8b7096d5143ac04293a7 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Wed, 9 May 2018 21:28:32 +0000 Subject: Split the MaybeOwned CPDF_Dictionary in CPDF_FlateEncoder. The owned copy needs to be modified, so it should be non-const. Whereas the unowned copy can be const. Add a GetClonedDict() method for accessing the modifiable dictionary. Change-Id: Ia7f6bcc5f917864cd1bbc7b5000a86f6e433ae9a Reviewed-on: https://pdfium-review.googlesource.com/32181 Reviewed-by: Henrique Nakashima Commit-Queue: Lei Zhang --- core/fpdfapi/edit/cpdf_creator.cpp | 4 ++-- core/fpdfapi/edit/cpdf_flateencoder.cpp | 38 +++++++++++++++++++++++++-------- core/fpdfapi/edit/cpdf_flateencoder.h | 14 +++++++++--- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/core/fpdfapi/edit/cpdf_creator.cpp b/core/fpdfapi/edit/cpdf_creator.cpp index 9176c21e45..872860b0ed 100644 --- a/core/fpdfapi/edit/cpdf_creator.cpp +++ b/core/fpdfapi/edit/cpdf_creator.cpp @@ -169,7 +169,7 @@ bool CPDF_Creator::WriteStream(const CPDF_Object* pStream, if (static_cast(encoder.GetDict()->GetIntegerFor("Length")) != encryptor.GetSize()) { encoder.CloneDict(); - encoder.GetDict()->SetNewFor( + encoder.GetClonedDict()->SetNewFor( "Length", static_cast(encryptor.GetSize())); } @@ -240,7 +240,7 @@ bool CPDF_Creator::WriteDirectObj(uint32_t objnum, if (static_cast(encoder.GetDict()->GetIntegerFor("Length")) != encryptor.GetSize()) { encoder.CloneDict(); - encoder.GetDict()->SetNewFor( + encoder.GetClonedDict()->SetNewFor( "Length", static_cast(encryptor.GetSize())); } if (!WriteDirectObj(objnum, encoder.GetDict(), true) || diff --git a/core/fpdfapi/edit/cpdf_flateencoder.cpp b/core/fpdfapi/edit/cpdf_flateencoder.cpp index f6125b8847..a290da6dac 100644 --- a/core/fpdfapi/edit/cpdf_flateencoder.cpp +++ b/core/fpdfapi/edit/cpdf_flateencoder.cpp @@ -25,14 +25,16 @@ CPDF_FlateEncoder::CPDF_FlateEncoder(const CPDF_Stream* pStream, m_dwSize = pDestAcc->GetSize(); m_pData = pDestAcc->DetachData(); - m_pDict = ToDictionary(pStream->GetDict()->Clone()); - m_pDict->RemoveFor("Filter"); + m_pClonedDict = ToDictionary(pStream->GetDict()->Clone()); + m_pClonedDict->RemoveFor("Filter"); + ASSERT(!m_pDict); return; } if (bHasFilter || !bFlateEncode) { m_pData = m_pAcc->GetData(); m_dwSize = m_pAcc->GetSize(); m_pDict = pStream->GetDict(); + ASSERT(!m_pClonedDict); return; } @@ -41,18 +43,36 @@ CPDF_FlateEncoder::CPDF_FlateEncoder(const CPDF_Stream* pStream, ::FlateEncode(m_pAcc->GetData(), m_pAcc->GetSize(), &buffer, &m_dwSize); m_pData = std::unique_ptr(buffer); - m_pDict = ToDictionary(pStream->GetDict()->Clone()); - m_pDict->SetNewFor("Length", static_cast(m_dwSize)); - m_pDict->SetNewFor("Filter", "FlateDecode"); - m_pDict->RemoveFor(pdfium::stream::kDecodeParms); + m_pClonedDict = ToDictionary(pStream->GetDict()->Clone()); + m_pClonedDict->SetNewFor("Length", static_cast(m_dwSize)); + m_pClonedDict->SetNewFor("Filter", "FlateDecode"); + m_pClonedDict->RemoveFor(pdfium::stream::kDecodeParms); + ASSERT(!m_pDict); } CPDF_FlateEncoder::~CPDF_FlateEncoder() {} void CPDF_FlateEncoder::CloneDict() { - if (m_pDict.IsOwned()) + if (m_pClonedDict) { + ASSERT(!m_pDict); return; + } + + m_pClonedDict = ToDictionary(m_pDict->Clone()); + ASSERT(m_pClonedDict); + m_pDict.Release(); +} + +CPDF_Dictionary* CPDF_FlateEncoder::GetClonedDict() { + ASSERT(!m_pDict); + return m_pClonedDict.get(); +} + +const CPDF_Dictionary* CPDF_FlateEncoder::GetDict() const { + if (m_pClonedDict) { + ASSERT(!m_pDict); + return m_pClonedDict.get(); + } - m_pDict = ToDictionary(m_pDict->Clone()); - ASSERT(m_pDict.IsOwned()); + return m_pDict.Get(); } diff --git a/core/fpdfapi/edit/cpdf_flateencoder.h b/core/fpdfapi/edit/cpdf_flateencoder.h index b2213de5f3..b69b54d93b 100644 --- a/core/fpdfapi/edit/cpdf_flateencoder.h +++ b/core/fpdfapi/edit/cpdf_flateencoder.h @@ -7,6 +7,8 @@ #ifndef CORE_FPDFAPI_EDIT_CPDF_FLATEENCODER_H_ #define CORE_FPDFAPI_EDIT_CPDF_FLATEENCODER_H_ +#include + #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_stream_acc.h" #include "core/fxcrt/fx_memory.h" @@ -21,16 +23,22 @@ class CPDF_FlateEncoder { ~CPDF_FlateEncoder(); void CloneDict(); + CPDF_Dictionary* GetClonedDict(); + + // Returns |m_pClonedDict| if it is valid. Otherwise returns |m_pDict|. + const CPDF_Dictionary* GetDict() const; uint32_t GetSize() const { return m_dwSize; } const uint8_t* GetData() const { return m_pData.Get(); } - CPDF_Dictionary* GetDict() { return m_pDict.Get(); } - private: uint32_t m_dwSize; MaybeOwned m_pData; - MaybeOwned m_pDict; + + // Only one of these two pointers is valid at any time. + UnownedPtr m_pDict; + std::unique_ptr m_pClonedDict; + RetainPtr m_pAcc; }; -- cgit v1.2.3