summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fpdfapi/edit/cpdf_creator.cpp2
-rw-r--r--core/fpdfapi/parser/cpdf_parser.cpp40
-rw-r--r--core/fpdfapi/parser/cpdf_parser.h6
3 files changed, 41 insertions, 7 deletions
diff --git a/core/fpdfapi/edit/cpdf_creator.cpp b/core/fpdfapi/edit/cpdf_creator.cpp
index 38abb85822..590229bf4f 100644
--- a/core/fpdfapi/edit/cpdf_creator.cpp
+++ b/core/fpdfapi/edit/cpdf_creator.cpp
@@ -624,7 +624,7 @@ int32_t CPDF_Creator::WriteDoc_Stage4() {
}
if (m_pParser) {
- CPDF_Dictionary* p = m_pParser->GetTrailer();
+ std::unique_ptr<CPDF_Dictionary> p = m_pParser->GetCombinedTrailer();
for (const auto& it : *p) {
const ByteString& key = it.first;
CPDF_Object* pValue = it.second.get();
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index d02989000c..5b57b949ba 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -61,6 +61,20 @@ class CPDF_Parser::TrailerData {
CPDF_Dictionary* GetMainTrailer() const { return main_trailer_.get(); }
+ std::unique_ptr<CPDF_Dictionary> GetCombinedTrailer() const {
+ std::unique_ptr<CPDF_Dictionary> result =
+ ToDictionary(main_trailer_->Clone());
+
+ // Info is optional.
+ uint32_t info_obj_num = GetInfoObjNum();
+ if (info_obj_num > 0)
+ result->SetNewFor<CPDF_Reference>("Info", nullptr, GetInfoObjNum());
+
+ // Root is required.
+ result->SetNewFor<CPDF_Reference>("Root", nullptr, GetRootObjNum());
+ return result;
+ }
+
void SetMainTrailer(std::unique_ptr<CPDF_Dictionary> trailer) {
ASSERT(trailer);
main_trailer_ = std::move(trailer);
@@ -75,6 +89,7 @@ class CPDF_Parser::TrailerData {
void Clear() {
main_trailer_.reset();
last_info_obj_num_ = 0;
+ last_root_obj_num_ = 0;
}
uint32_t GetInfoObjNum() const {
@@ -83,6 +98,12 @@ class CPDF_Parser::TrailerData {
return pRef ? pRef->GetRefObjNum() : last_info_obj_num_;
}
+ uint32_t GetRootObjNum() const {
+ const CPDF_Reference* pRef = ToReference(
+ GetMainTrailer() ? GetMainTrailer()->GetObjectFor("Root") : nullptr);
+ return pRef ? pRef->GetRefObjNum() : last_root_obj_num_;
+ }
+
private:
void ApplyTrailer(const CPDF_Dictionary* dict) {
// The most recent Info object number contained in last added trailer.
@@ -90,10 +111,15 @@ class CPDF_Parser::TrailerData {
const auto* pRef = ToReference(dict->GetObjectFor("Info"));
if (pRef)
last_info_obj_num_ = pRef->GetRefObjNum();
+
+ const auto* pRoot = ToReference(dict->GetObjectFor("Root"));
+ if (pRoot)
+ last_root_obj_num_ = pRoot->GetRefObjNum();
}
std::unique_ptr<CPDF_Dictionary> main_trailer_;
uint32_t last_info_obj_num_ = 0;
+ uint32_t last_root_obj_num_ = 0;
};
CPDF_Parser::CPDF_Parser()
@@ -1145,20 +1171,22 @@ const CPDF_Array* CPDF_Parser::GetIDArray() const {
return GetTrailer() ? GetTrailer()->GetArrayFor("ID") : nullptr;
}
-uint32_t CPDF_Parser::GetRootObjNum() {
- CPDF_Reference* pRef =
- ToReference(GetTrailer() ? GetTrailer()->GetObjectFor("Root") : nullptr);
- return pRef ? pRef->GetRefObjNum() : 0;
-}
-
CPDF_Dictionary* CPDF_Parser::GetTrailer() const {
return m_TrailerData->GetMainTrailer();
}
+std::unique_ptr<CPDF_Dictionary> CPDF_Parser::GetCombinedTrailer() const {
+ return m_TrailerData->GetCombinedTrailer();
+}
+
uint32_t CPDF_Parser::GetInfoObjNum() {
return m_TrailerData->GetInfoObjNum();
}
+uint32_t CPDF_Parser::GetRootObjNum() {
+ return m_TrailerData->GetRootObjNum();
+}
+
std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObject(
CPDF_IndirectObjectHolder* pObjList,
uint32_t objnum) {
diff --git a/core/fpdfapi/parser/cpdf_parser.h b/core/fpdfapi/parser/cpdf_parser.h
index 375bc01621..45b8cb9f2e 100644
--- a/core/fpdfapi/parser/cpdf_parser.h
+++ b/core/fpdfapi/parser/cpdf_parser.h
@@ -57,7 +57,13 @@ class CPDF_Parser {
void SetPassword(const char* password) { m_Password = password; }
ByteString GetPassword() { return m_Password; }
+
CPDF_Dictionary* GetTrailer() const;
+
+ // Returns a new trailer which combines the last read trailer with the /Root
+ // and /Info from previous ones.
+ std::unique_ptr<CPDF_Dictionary> GetCombinedTrailer() const;
+
FX_FILESIZE GetLastXRefOffset() const { return m_LastXRefOffset; }
uint32_t GetPermissions() const;