Stop vending dictionary pointers from CPDF_FlateEncoder
Moving code from CPDF_Stream to CPDF_FlateEncoder better encapsulates
the dictionary members.
Change-Id: I887d6e39b160dea58cac971b480d074c3e078332
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/98717
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_flateencoder.cpp b/core/fpdfapi/parser/cpdf_flateencoder.cpp
index 49d5bf8..7b6bdb8 100644
--- a/core/fpdfapi/parser/cpdf_flateencoder.cpp
+++ b/core/fpdfapi/parser/cpdf_flateencoder.cpp
@@ -51,20 +51,22 @@
CPDF_FlateEncoder::~CPDF_FlateEncoder() = default;
-void CPDF_FlateEncoder::CloneDict() {
- if (m_pClonedDict) {
- DCHECK(!m_pDict);
+void CPDF_FlateEncoder::UpdateLength(size_t size) {
+ if (static_cast<size_t>(GetDict()->GetIntegerFor("Length")) == size)
return;
- }
- m_pClonedDict = ToDictionary(m_pDict->Clone());
+ if (!m_pClonedDict) {
+ m_pClonedDict = ToDictionary(m_pDict->Clone());
+ m_pDict.Reset();
+ }
DCHECK(m_pClonedDict);
- m_pDict.Reset();
+ DCHECK(!m_pDict);
+ m_pClonedDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(size));
}
-CPDF_Dictionary* CPDF_FlateEncoder::GetClonedDict() {
- DCHECK(!m_pDict);
- return m_pClonedDict.Get();
+bool CPDF_FlateEncoder::WriteDictTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const {
+ return GetDict()->WriteTo(archive, encryptor);
}
const CPDF_Dictionary* CPDF_FlateEncoder::GetDict() const {
@@ -72,7 +74,6 @@
DCHECK(!m_pDict);
return m_pClonedDict.Get();
}
-
return m_pDict.Get();
}
diff --git a/core/fpdfapi/parser/cpdf_flateencoder.h b/core/fpdfapi/parser/cpdf_flateencoder.h
index 7e6c797..3d412e2 100644
--- a/core/fpdfapi/parser/cpdf_flateencoder.h
+++ b/core/fpdfapi/parser/cpdf_flateencoder.h
@@ -15,25 +15,28 @@
#include "third_party/base/span.h"
class CPDF_Dictionary;
+class CPDF_Encryptor;
class CPDF_Stream;
class CPDF_StreamAcc;
+class IFX_ArchiveStream;
class CPDF_FlateEncoder {
public:
CPDF_FlateEncoder(RetainPtr<const CPDF_Stream> pStream, bool bFlateEncode);
~CPDF_FlateEncoder();
- void CloneDict();
- CPDF_Dictionary* GetClonedDict();
-
- // Returns |m_pClonedDict| if it is valid. Otherwise returns |m_pDict|.
- const CPDF_Dictionary* GetDict() const;
+ void UpdateLength(size_t size);
+ bool WriteDictTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const;
pdfium::span<const uint8_t> GetSpan() const;
private:
bool is_owned() const { return m_Data.index() == 1; }
+ // Returns |m_pClonedDict| if it is valid. Otherwise returns |m_pDict|.
+ const CPDF_Dictionary* GetDict() const;
+
// Must outlive `m_Data`.
RetainPtr<CPDF_StreamAcc> const m_pAcc;
diff --git a/core/fpdfapi/parser/cpdf_stream.cpp b/core/fpdfapi/parser/cpdf_stream.cpp
index 341e6ac..763f5e0 100644
--- a/core/fpdfapi/parser/cpdf_stream.cpp
+++ b/core/fpdfapi/parser/cpdf_stream.cpp
@@ -193,20 +193,13 @@
DataVector<uint8_t> encrypted_data;
pdfium::span<const uint8_t> data = encoder.GetSpan();
-
if (encryptor && !is_metadata) {
encrypted_data = encryptor->Encrypt(data);
data = encrypted_data;
}
- const size_t size = data.size();
- if (static_cast<size_t>(encoder.GetDict()->GetIntegerFor("Length")) != size) {
- encoder.CloneDict();
- encoder.GetClonedDict()->SetNewFor<CPDF_Number>("Length",
- static_cast<int>(size));
- }
-
- if (!encoder.GetDict()->WriteTo(archive, encryptor))
+ encoder.UpdateLength(data.size());
+ if (!encoder.WriteDictTo(archive, encryptor))
return false;
if (!archive->WriteString("stream\r\n"))