summaryrefslogtreecommitdiff
path: root/core/fpdfapi/parser
diff options
context:
space:
mode:
Diffstat (limited to 'core/fpdfapi/parser')
-rw-r--r--core/fpdfapi/parser/cpdf_array.cpp5
-rw-r--r--core/fpdfapi/parser/cpdf_array.h3
-rw-r--r--core/fpdfapi/parser/cpdf_boolean.cpp3
-rw-r--r--core/fpdfapi/parser/cpdf_boolean.h3
-rw-r--r--core/fpdfapi/parser/cpdf_dictionary.cpp11
-rw-r--r--core/fpdfapi/parser/cpdf_dictionary.h3
-rw-r--r--core/fpdfapi/parser/cpdf_name.cpp3
-rw-r--r--core/fpdfapi/parser/cpdf_name.h3
-rw-r--r--core/fpdfapi/parser/cpdf_null.cpp3
-rw-r--r--core/fpdfapi/parser/cpdf_null.h3
-rw-r--r--core/fpdfapi/parser/cpdf_number.cpp3
-rw-r--r--core/fpdfapi/parser/cpdf_number.h3
-rw-r--r--core/fpdfapi/parser/cpdf_object.h4
-rw-r--r--core/fpdfapi/parser/cpdf_reference.cpp3
-rw-r--r--core/fpdfapi/parser/cpdf_reference.h3
-rw-r--r--core/fpdfapi/parser/cpdf_stream.cpp45
-rw-r--r--core/fpdfapi/parser/cpdf_stream.h3
-rw-r--r--core/fpdfapi/parser/cpdf_string.cpp16
-rw-r--r--core/fpdfapi/parser/cpdf_string.h3
19 files changed, 94 insertions, 29 deletions
diff --git a/core/fpdfapi/parser/cpdf_array.cpp b/core/fpdfapi/parser/cpdf_array.cpp
index d53476d1c2..68b301e283 100644
--- a/core/fpdfapi/parser/cpdf_array.cpp
+++ b/core/fpdfapi/parser/cpdf_array.cpp
@@ -230,12 +230,13 @@ CPDF_Object* CPDF_Array::Add(std::unique_ptr<CPDF_Object> pObj) {
return pRet;
}
-bool CPDF_Array::WriteTo(IFX_ArchiveStream* archive) const {
+bool CPDF_Array::WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const {
if (!archive->WriteString("["))
return false;
for (size_t i = 0; i < GetCount(); ++i) {
- if (!GetObjectAt(i)->WriteTo(archive))
+ if (!GetObjectAt(i)->WriteTo(archive, encryptor))
return false;
}
return archive->WriteString("]");
diff --git a/core/fpdfapi/parser/cpdf_array.h b/core/fpdfapi/parser/cpdf_array.h
index d980b14507..1e63983d51 100644
--- a/core/fpdfapi/parser/cpdf_array.h
+++ b/core/fpdfapi/parser/cpdf_array.h
@@ -33,7 +33,8 @@ class CPDF_Array : public CPDF_Object {
bool IsArray() const override;
CPDF_Array* AsArray() override;
const CPDF_Array* AsArray() const override;
- bool WriteTo(IFX_ArchiveStream* archive) const override;
+ bool WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const override;
bool IsEmpty() const { return m_Objects.empty(); }
size_t GetCount() const { return m_Objects.size(); }
diff --git a/core/fpdfapi/parser/cpdf_boolean.cpp b/core/fpdfapi/parser/cpdf_boolean.cpp
index a1dc450519..a26110116b 100644
--- a/core/fpdfapi/parser/cpdf_boolean.cpp
+++ b/core/fpdfapi/parser/cpdf_boolean.cpp
@@ -46,7 +46,8 @@ const CPDF_Boolean* CPDF_Boolean::AsBoolean() const {
return this;
}
-bool CPDF_Boolean::WriteTo(IFX_ArchiveStream* archive) const {
+bool CPDF_Boolean::WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const {
return archive->WriteString(" ") &&
archive->WriteString(GetString().AsStringView());
}
diff --git a/core/fpdfapi/parser/cpdf_boolean.h b/core/fpdfapi/parser/cpdf_boolean.h
index c0a69d8932..61c213bdb9 100644
--- a/core/fpdfapi/parser/cpdf_boolean.h
+++ b/core/fpdfapi/parser/cpdf_boolean.h
@@ -28,7 +28,8 @@ class CPDF_Boolean : public CPDF_Object {
bool IsBoolean() const override;
CPDF_Boolean* AsBoolean() override;
const CPDF_Boolean* AsBoolean() const override;
- bool WriteTo(IFX_ArchiveStream* archive) const override;
+ bool WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const override;
protected:
bool m_bValue;
diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp
index 78227ae70a..585930427c 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.cpp
+++ b/core/fpdfapi/parser/cpdf_dictionary.cpp
@@ -269,10 +269,13 @@ ByteString CPDF_Dictionary::MaybeIntern(const ByteString& str) {
return m_pPool ? m_pPool->Intern(str) : str;
}
-bool CPDF_Dictionary::WriteTo(IFX_ArchiveStream* archive) const {
+bool CPDF_Dictionary::WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const {
if (!archive->WriteString("<<"))
return false;
+ const bool is_signature = CPDF_CryptoHandler::IsSignatureDictionary(this);
+
for (const auto& it : *this) {
const ByteString& key = it.first;
CPDF_Object* pValue = it.second.get();
@@ -280,9 +283,11 @@ bool CPDF_Dictionary::WriteTo(IFX_ArchiveStream* archive) const {
!archive->WriteString(PDF_NameEncode(key).AsStringView())) {
return false;
}
-
- if (!pValue->WriteTo(archive))
+ if (!pValue->WriteTo(archive, !is_signature || key != "Contents"
+ ? encryptor
+ : nullptr)) {
return false;
+ }
}
return archive->WriteString(">>");
}
diff --git a/core/fpdfapi/parser/cpdf_dictionary.h b/core/fpdfapi/parser/cpdf_dictionary.h
index 569baedb0b..5cd0e8be22 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.h
+++ b/core/fpdfapi/parser/cpdf_dictionary.h
@@ -38,7 +38,8 @@ class CPDF_Dictionary : public CPDF_Object {
bool IsDictionary() const override;
CPDF_Dictionary* AsDictionary() override;
const CPDF_Dictionary* AsDictionary() const override;
- bool WriteTo(IFX_ArchiveStream* archive) const override;
+ bool WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const override;
size_t GetCount() const { return m_Map.size(); }
const CPDF_Object* GetObjectFor(const ByteString& key) const;
diff --git a/core/fpdfapi/parser/cpdf_name.cpp b/core/fpdfapi/parser/cpdf_name.cpp
index 59a014208b..d35a76c8a0 100644
--- a/core/fpdfapi/parser/cpdf_name.cpp
+++ b/core/fpdfapi/parser/cpdf_name.cpp
@@ -51,7 +51,8 @@ WideString CPDF_Name::GetUnicodeText() const {
return PDF_DecodeText(m_Name);
}
-bool CPDF_Name::WriteTo(IFX_ArchiveStream* archive) const {
+bool CPDF_Name::WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const {
return archive->WriteString("/") &&
archive->WriteString(PDF_NameEncode(GetString()).AsStringView());
}
diff --git a/core/fpdfapi/parser/cpdf_name.h b/core/fpdfapi/parser/cpdf_name.h
index 880c10aedb..eef6bca715 100644
--- a/core/fpdfapi/parser/cpdf_name.h
+++ b/core/fpdfapi/parser/cpdf_name.h
@@ -27,7 +27,8 @@ class CPDF_Name : public CPDF_Object {
bool IsName() const override;
CPDF_Name* AsName() override;
const CPDF_Name* AsName() const override;
- bool WriteTo(IFX_ArchiveStream* archive) const override;
+ bool WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const override;
protected:
ByteString m_Name;
diff --git a/core/fpdfapi/parser/cpdf_null.cpp b/core/fpdfapi/parser/cpdf_null.cpp
index 1074efd863..f94b46778b 100644
--- a/core/fpdfapi/parser/cpdf_null.cpp
+++ b/core/fpdfapi/parser/cpdf_null.cpp
@@ -18,7 +18,8 @@ std::unique_ptr<CPDF_Object> CPDF_Null::Clone() const {
return pdfium::MakeUnique<CPDF_Null>();
}
-bool CPDF_Null::WriteTo(IFX_ArchiveStream* archive) const {
+bool CPDF_Null::WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const {
return archive->WriteString(" null");
}
diff --git a/core/fpdfapi/parser/cpdf_null.h b/core/fpdfapi/parser/cpdf_null.h
index 2ec05ec82c..003ad2feee 100644
--- a/core/fpdfapi/parser/cpdf_null.h
+++ b/core/fpdfapi/parser/cpdf_null.h
@@ -18,7 +18,8 @@ class CPDF_Null : public CPDF_Object {
// CPDF_Object.
Type GetType() const override;
std::unique_ptr<CPDF_Object> Clone() const override;
- bool WriteTo(IFX_ArchiveStream* archive) const override;
+ bool WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const override;
bool IsNull() const override;
};
diff --git a/core/fpdfapi/parser/cpdf_number.cpp b/core/fpdfapi/parser/cpdf_number.cpp
index dac1f40b7f..b75ce0766a 100644
--- a/core/fpdfapi/parser/cpdf_number.cpp
+++ b/core/fpdfapi/parser/cpdf_number.cpp
@@ -57,7 +57,8 @@ ByteString CPDF_Number::GetString() const {
: ByteString::FormatFloat(m_Float);
}
-bool CPDF_Number::WriteTo(IFX_ArchiveStream* archive) const {
+bool CPDF_Number::WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const {
return archive->WriteString(" ") &&
archive->WriteString(GetString().AsStringView());
}
diff --git a/core/fpdfapi/parser/cpdf_number.h b/core/fpdfapi/parser/cpdf_number.h
index 661177363b..4681bb216a 100644
--- a/core/fpdfapi/parser/cpdf_number.h
+++ b/core/fpdfapi/parser/cpdf_number.h
@@ -31,7 +31,8 @@ class CPDF_Number : public CPDF_Object {
bool IsNumber() const override;
CPDF_Number* AsNumber() override;
const CPDF_Number* AsNumber() const override;
- bool WriteTo(IFX_ArchiveStream* archive) const override;
+ bool WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const override;
bool IsInteger() const { return m_bInteger; }
diff --git a/core/fpdfapi/parser/cpdf_object.h b/core/fpdfapi/parser/cpdf_object.h
index 5ff028e9e0..6c6b583963 100644
--- a/core/fpdfapi/parser/cpdf_object.h
+++ b/core/fpdfapi/parser/cpdf_object.h
@@ -17,6 +17,7 @@
class CPDF_Array;
class CPDF_Boolean;
class CPDF_Dictionary;
+class CPDF_Encryptor;
class CPDF_IndirectObjectHolder;
class CPDF_Name;
class CPDF_Null;
@@ -95,7 +96,8 @@ class CPDF_Object {
virtual CPDF_String* AsString();
virtual const CPDF_String* AsString() const;
- virtual bool WriteTo(IFX_ArchiveStream* archive) const = 0;
+ virtual bool WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const = 0;
// Create a deep copy of the object with the option to either
// copy a reference object or directly copy the object it refers to
diff --git a/core/fpdfapi/parser/cpdf_reference.cpp b/core/fpdfapi/parser/cpdf_reference.cpp
index 0f3b7627d6..5a4d58a0e2 100644
--- a/core/fpdfapi/parser/cpdf_reference.cpp
+++ b/core/fpdfapi/parser/cpdf_reference.cpp
@@ -99,7 +99,8 @@ const CPDF_Object* CPDF_Reference::GetDirect() const {
: nullptr;
}
-bool CPDF_Reference::WriteTo(IFX_ArchiveStream* archive) const {
+bool CPDF_Reference::WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const {
return archive->WriteString(" ") && archive->WriteDWord(GetRefObjNum()) &&
archive->WriteString(" 0 R ");
}
diff --git a/core/fpdfapi/parser/cpdf_reference.h b/core/fpdfapi/parser/cpdf_reference.h
index d1e0a07e4b..cdb5d5e674 100644
--- a/core/fpdfapi/parser/cpdf_reference.h
+++ b/core/fpdfapi/parser/cpdf_reference.h
@@ -33,7 +33,8 @@ class CPDF_Reference : public CPDF_Object {
bool IsReference() const override;
CPDF_Reference* AsReference() override;
const CPDF_Reference* AsReference() const override;
- bool WriteTo(IFX_ArchiveStream* archive) const override;
+ bool WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const override;
std::unique_ptr<CPDF_Object> MakeReference(
CPDF_IndirectObjectHolder* holder) const override;
diff --git a/core/fpdfapi/parser/cpdf_stream.cpp b/core/fpdfapi/parser/cpdf_stream.cpp
index fdbe308878..64478996a8 100644
--- a/core/fpdfapi/parser/cpdf_stream.cpp
+++ b/core/fpdfapi/parser/cpdf_stream.cpp
@@ -7,8 +7,11 @@
#include "core/fpdfapi/parser/cpdf_stream.h"
#include <utility>
+#include <vector>
#include "constants/stream_dict_common.h"
+#include "core/fpdfapi/edit/cpdf_encryptor.h"
+#include "core/fpdfapi/edit/cpdf_flateencoder.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_number.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
@@ -18,6 +21,15 @@
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"
+namespace {
+
+bool IsMetaDataStreamDictionary(const CPDF_Dictionary* dict) {
+ return dict && dict->GetStringFor("Type") == "Metadata" &&
+ dict->GetStringFor("Subtype") == "XML";
+}
+
+} // namespace
+
CPDF_Stream::CPDF_Stream() {}
CPDF_Stream::CPDF_Stream(std::unique_ptr<uint8_t, FxFreeDeleter> pData,
@@ -167,12 +179,33 @@ WideString CPDF_Stream::GetUnicodeText() const {
return PDF_DecodeText(pAcc->GetData(), pAcc->GetSize());
}
-bool CPDF_Stream::WriteTo(IFX_ArchiveStream* archive) const {
- if (!GetDict()->WriteTo(archive) || !archive->WriteString("stream\r\n"))
+bool CPDF_Stream::WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const {
+ const bool is_metadata = IsMetaDataStreamDictionary(GetDict());
+ CPDF_FlateEncoder encoder(this, !is_metadata);
+
+ std::vector<uint8_t> encrypted_data;
+ pdfium::span<const uint8_t> data = encoder.GetSpan();
+
+ if (encryptor && !is_metadata) {
+ encrypted_data = encryptor->Encrypt(data);
+ data = encrypted_data;
+ }
+
+ if (static_cast<uint32_t>(encoder.GetDict()->GetIntegerFor("Length")) !=
+ data.size()) {
+ encoder.CloneDict();
+ encoder.GetClonedDict()->SetNewFor<CPDF_Number>(
+ "Length", static_cast<int>(data.size()));
+ }
+
+ if (!encoder.GetDict()->WriteTo(archive, encryptor))
return false;
- auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(this);
- pAcc->LoadAllDataRaw();
- return archive->WriteBlock(pAcc->GetData(), pAcc->GetSize()) &&
- archive->WriteString("\r\nendstream");
+ if (!archive->WriteString("stream\r\n") ||
+ !archive->WriteBlock(data.data(), data.size()) ||
+ !archive->WriteString("\r\nendstream")) {
+ return false;
+ }
+ return true;
}
diff --git a/core/fpdfapi/parser/cpdf_stream.h b/core/fpdfapi/parser/cpdf_stream.h
index 7e98f300ba..4a5ac61011 100644
--- a/core/fpdfapi/parser/cpdf_stream.h
+++ b/core/fpdfapi/parser/cpdf_stream.h
@@ -34,7 +34,8 @@ class CPDF_Stream : public CPDF_Object {
bool IsStream() const override;
CPDF_Stream* AsStream() override;
const CPDF_Stream* AsStream() const override;
- bool WriteTo(IFX_ArchiveStream* archive) const override;
+ bool WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const override;
uint32_t GetRawSize() const { return m_dwSize; }
// Will be null in case when stream is not memory based.
diff --git a/core/fpdfapi/parser/cpdf_string.cpp b/core/fpdfapi/parser/cpdf_string.cpp
index 851442e8b4..e7f2a9dcd6 100644
--- a/core/fpdfapi/parser/cpdf_string.cpp
+++ b/core/fpdfapi/parser/cpdf_string.cpp
@@ -7,7 +7,9 @@
#include "core/fpdfapi/parser/cpdf_string.h"
#include <utility>
+#include <vector>
+#include "core/fpdfapi/edit/cpdf_encryptor.h"
#include "core/fpdfapi/parser/fpdf_parser_decode.h"
#include "core/fxcrt/fx_stream.h"
#include "third_party/base/ptr_util.h"
@@ -65,7 +67,15 @@ WideString CPDF_String::GetUnicodeText() const {
return PDF_DecodeText(m_String);
}
-bool CPDF_String::WriteTo(IFX_ArchiveStream* archive) const {
- return archive->WriteString(
- PDF_EncodeString(GetString(), IsHex()).AsStringView());
+bool CPDF_String::WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const {
+ std::vector<uint8_t> encrypted_data;
+ pdfium::span<const uint8_t> data = m_String.AsRawSpan();
+ if (encryptor) {
+ encrypted_data = encryptor->Encrypt(data);
+ data = encrypted_data;
+ }
+ const ByteString content =
+ PDF_EncodeString(ByteString(data.data(), data.size()), IsHex());
+ return archive->WriteString(content.AsStringView());
}
diff --git a/core/fpdfapi/parser/cpdf_string.h b/core/fpdfapi/parser/cpdf_string.h
index b6aaacb043..144fe64cba 100644
--- a/core/fpdfapi/parser/cpdf_string.h
+++ b/core/fpdfapi/parser/cpdf_string.h
@@ -31,7 +31,8 @@ class CPDF_String : public CPDF_Object {
bool IsString() const override;
CPDF_String* AsString() override;
const CPDF_String* AsString() const override;
- bool WriteTo(IFX_ArchiveStream* archive) const override;
+ bool WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const override;
bool IsHex() const { return m_bHex; }