diff options
-rw-r--r-- | core/fpdfapi/edit/cpdf_creator.cpp | 2 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_parser.cpp | 40 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_parser.h | 6 |
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; |