diff options
Diffstat (limited to 'core/fpdfapi/parser/cpdf_parser.cpp')
-rw-r--r-- | core/fpdfapi/parser/cpdf_parser.cpp | 103 |
1 files changed, 57 insertions, 46 deletions
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp index c7a3fe16c8..3986f3684f 100644 --- a/core/fpdfapi/parser/cpdf_parser.cpp +++ b/core/fpdfapi/parser/cpdf_parser.cpp @@ -47,6 +47,13 @@ uint32_t GetVarInt(const uint8_t* p, int32_t n) { return result; } +class ObjectsHolderStub : public CPDF_Parser::ParsedObjectsHolder { + public: + ObjectsHolderStub() = default; + ~ObjectsHolderStub() override = default; + bool TryInit() override { return true; } +}; + } // namespace class CPDF_Parser::TrailerData { @@ -117,12 +124,20 @@ class CPDF_Parser::TrailerData { uint32_t last_root_obj_num_ = CPDF_Object::kInvalidObjNum; }; -CPDF_Parser::CPDF_Parser() +CPDF_Parser::CPDF_Parser(ParsedObjectsHolder* holder) : m_pSyntax(pdfium::MakeUnique<CPDF_SyntaxParser>()), + m_pObjectsHolder(holder), m_bHasParsed(false), m_bXRefStream(false), m_FileVersion(0), - m_TrailerData(pdfium::MakeUnique<TrailerData>()) {} + m_TrailerData(pdfium::MakeUnique<TrailerData>()) { + if (!holder) { + m_pOwnedObjectsHolder = pdfium::MakeUnique<ObjectsHolderStub>(); + m_pObjectsHolder = m_pOwnedObjectsHolder.get(); + } +} + +CPDF_Parser::CPDF_Parser() : CPDF_Parser(nullptr) {} CPDF_Parser::~CPDF_Parser() { ReleaseEncryptHandler(); @@ -225,20 +240,19 @@ bool CPDF_Parser::ParseFileVersion() { CPDF_Parser::Error CPDF_Parser::StartParse( const RetainPtr<IFX_SeekableReadStream>& pFileAccess, - CPDF_Document* pDocument) { + const char* password) { if (!InitSyntaxParser( pdfium::MakeRetain<CPDF_ReadValidator>(pFileAccess, nullptr))) return FORMAT_ERROR; - return StartParseInternal(pDocument); + SetPassword(password); + return StartParseInternal(); } -CPDF_Parser::Error CPDF_Parser::StartParseInternal(CPDF_Document* pDocument) { +CPDF_Parser::Error CPDF_Parser::StartParseInternal() { ASSERT(!m_bHasParsed); m_bHasParsed = true; m_bXRefStream = false; - m_pDocument = pDocument; - bool bXRefRebuilt = false; m_LastXRefOffset = ParseStartXRef(); @@ -262,8 +276,7 @@ CPDF_Parser::Error CPDF_Parser::StartParseInternal(CPDF_Document* pDocument) { if (eRet != SUCCESS) return eRet; - m_pDocument->LoadDoc(); - if (!m_pDocument->GetRoot() || m_pDocument->GetPageCount() == 0) { + if (!GetRoot() || !m_pObjectsHolder->TryInit()) { if (bXRefRebuilt) return FORMAT_ERROR; @@ -275,8 +288,8 @@ CPDF_Parser::Error CPDF_Parser::StartParseInternal(CPDF_Document* pDocument) { if (eRet != SUCCESS) return eRet; - m_pDocument->LoadDoc(); - if (!m_pDocument->GetRoot()) + m_pObjectsHolder->TryInit(); + if (!GetRoot()) return FORMAT_ERROR; } if (GetRootObjNum() == CPDF_Object::kInvalidObjNum) { @@ -290,7 +303,7 @@ CPDF_Parser::Error CPDF_Parser::StartParseInternal(CPDF_Document* pDocument) { } if (m_pSecurityHandler && !m_pSecurityHandler->IsMetadataEncrypted()) { CPDF_Reference* pMetadata = - ToReference(m_pDocument->GetRoot()->GetObjectFor("Metadata")); + ToReference(GetRoot()->GetObjectFor("Metadata")); if (pMetadata) m_MetadataObjnum = pMetadata->GetRefObjNum(); } @@ -330,7 +343,8 @@ CPDF_Parser::Error CPDF_Parser::SetEncryptHandler() { if (CPDF_Dictionary* pEncryptDict = pEncryptObj->AsDictionary()) { SetEncryptDictionary(pEncryptDict); } else if (CPDF_Reference* pRef = pEncryptObj->AsReference()) { - pEncryptObj = m_pDocument->GetOrParseIndirectObject(pRef->GetRefObjNum()); + pEncryptObj = + m_pObjectsHolder->GetOrParseIndirectObject(pRef->GetRefObjNum()); if (pEncryptObj) SetEncryptDictionary(pEncryptObj->GetDict()); } @@ -955,8 +969,7 @@ bool CPDF_Parser::RebuildCrossRef() { } bool CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, bool bMainXRef) { - std::unique_ptr<CPDF_Object> pObject( - ParseIndirectObjectAt(m_pDocument.Get(), *pos, 0)); + std::unique_ptr<CPDF_Object> pObject(ParseIndirectObjectAt(*pos, 0)); if (!pObject) return false; @@ -965,14 +978,12 @@ bool CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, bool bMainXRef) { return false; CPDF_Object* pUnownedObject = pObject.get(); - if (m_pDocument) { - const CPDF_Dictionary* pRootDict = m_pDocument->GetRoot(); - if (pRootDict && pRootDict->GetObjNum() == objnum) - return false; - if (!m_pDocument->ReplaceIndirectObjectIfHigherGeneration( - objnum, std::move(pObject))) { - return false; - } + const CPDF_Dictionary* pRootDict = GetRoot(); + if (pRootDict && pRootDict->GetObjNum() == objnum) + return false; + if (!m_pObjectsHolder->ReplaceIndirectObjectIfHigherGeneration( + objnum, std::move(pObject))) { + return false; } CPDF_Stream* pStream = pUnownedObject->AsStream(); @@ -1104,6 +1115,12 @@ const CPDF_Array* CPDF_Parser::GetIDArray() const { return GetTrailer() ? GetTrailer()->GetArrayFor("ID") : nullptr; } +CPDF_Dictionary* CPDF_Parser::GetRoot() const { + CPDF_Object* obj = + m_pObjectsHolder->GetOrParseIndirectObject(GetRootObjNum()); + return obj ? obj->GetDict() : nullptr; +} + CPDF_Dictionary* CPDF_Parser::GetTrailer() const { return m_TrailerData->GetMainTrailer(); } @@ -1121,7 +1138,6 @@ uint32_t CPDF_Parser::GetRootObjNum() const { } std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObject( - CPDF_IndirectObjectHolder* pObjList, uint32_t objnum) { if (!IsValidObjectNumber(objnum)) return nullptr; @@ -1135,22 +1151,20 @@ std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObject( FX_FILESIZE pos = m_ObjectInfo[objnum].pos; if (pos <= 0) return nullptr; - return ParseIndirectObjectAt(pObjList, pos, objnum); + return ParseIndirectObjectAt(pos, objnum); } if (GetObjectType(objnum) != ObjectType::kCompressed) return nullptr; const CPDF_ObjectStream* pObjStream = - GetObjectStream(pObjList, m_ObjectInfo[objnum].pos); + GetObjectStream(m_ObjectInfo[objnum].pos); if (!pObjStream) return nullptr; - return pObjStream->ParseObject(pObjList, objnum); + return pObjStream->ParseObject(m_pObjectsHolder.Get(), objnum); } -const CPDF_ObjectStream* CPDF_Parser::GetObjectStream( - CPDF_IndirectObjectHolder* pObjList, - uint32_t object_number) { +const CPDF_ObjectStream* CPDF_Parser::GetObjectStream(uint32_t object_number) { // Prevent circular parsing the same object. if (pdfium::ContainsKey(m_ParsingObjNums, object_number)) return nullptr; @@ -1167,7 +1181,7 @@ const CPDF_ObjectStream* CPDF_Parser::GetObjectStream( return nullptr; std::unique_ptr<CPDF_Object> object = - ParseIndirectObjectAt(pObjList, object_pos, object_number); + ParseIndirectObjectAt(object_pos, object_number); if (!object) return nullptr; @@ -1180,22 +1194,21 @@ const CPDF_ObjectStream* CPDF_Parser::GetObjectStream( } std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObjectAt( - CPDF_IndirectObjectHolder* pObjList, FX_FILESIZE pos, uint32_t objnum) { return ParseIndirectObjectAtInternal( - pObjList, pos, objnum, CPDF_SyntaxParser::ParseType::kLoose, nullptr); + pos, objnum, CPDF_SyntaxParser::ParseType::kLoose, nullptr); } std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObjectAtInternal( - CPDF_IndirectObjectHolder* pObjList, FX_FILESIZE pos, uint32_t objnum, CPDF_SyntaxParser::ParseType parse_type, FX_FILESIZE* pResultPos) { const FX_FILESIZE saved_pos = m_pSyntax->GetPos(); m_pSyntax->SetPos(pos); - auto result = m_pSyntax->GetIndirectObject(pObjList, parse_type); + auto result = + m_pSyntax->GetIndirectObject(m_pObjectsHolder.Get(), parse_type); if (pResultPos) *pResultPos = m_pSyntax->GetPos(); @@ -1215,12 +1228,11 @@ std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObjectAtInternal( } std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObjectAtByStrict( - CPDF_IndirectObjectHolder* pObjList, FX_FILESIZE pos, uint32_t objnum, FX_FILESIZE* pResultPos) { return ParseIndirectObjectAtInternal( - pObjList, pos, objnum, CPDF_SyntaxParser::ParseType::kStrict, pResultPos); + pos, objnum, CPDF_SyntaxParser::ParseType::kStrict, pResultPos); } uint32_t CPDF_Parser::GetFirstPageNo() const { @@ -1236,7 +1248,7 @@ std::unique_ptr<CPDF_Dictionary> CPDF_Parser::LoadTrailerV4() { if (m_pSyntax->GetKeyword() != "trailer") return nullptr; - return ToDictionary(m_pSyntax->GetObjectBody(m_pDocument.Get())); + return ToDictionary(m_pSyntax->GetObjectBody(m_pObjectsHolder.Get())); } uint32_t CPDF_Parser::GetPermissions() const { @@ -1258,8 +1270,9 @@ std::unique_ptr<CPDF_LinearizedHeader> CPDF_Parser::ParseLinearizedHeader() { CPDF_Parser::Error CPDF_Parser::StartLinearizedParse( const RetainPtr<CPDF_ReadValidator>& validator, - CPDF_Document* pDocument) { + const char* password) { ASSERT(!m_bHasParsed); + SetPassword(password); m_bXRefStream = false; m_LastXRefOffset = 0; @@ -1268,10 +1281,9 @@ CPDF_Parser::Error CPDF_Parser::StartLinearizedParse( m_pLinearized = ParseLinearizedHeader(); if (!m_pLinearized) - return StartParseInternal(std::move(pDocument)); + return StartParseInternal(); m_bHasParsed = true; - m_pDocument = pDocument; m_LastXRefOffset = m_pLinearized->GetLastXRefOffset(); FX_FILESIZE dwFirstXRefOffset = m_LastXRefOffset; @@ -1299,8 +1311,7 @@ CPDF_Parser::Error CPDF_Parser::StartLinearizedParse( if (eRet != SUCCESS) return eRet; - m_pDocument->LoadDoc(); - if (!m_pDocument->GetRoot() || m_pDocument->GetPageCount() == 0) { + if (!GetRoot() || !m_pObjectsHolder->TryInit()) { if (bXRefRebuilt) return FORMAT_ERROR; @@ -1312,8 +1323,8 @@ CPDF_Parser::Error CPDF_Parser::StartLinearizedParse( if (eRet != SUCCESS) return eRet; - m_pDocument->LoadDoc(); - if (!m_pDocument->GetRoot()) + m_pObjectsHolder->TryInit(); + if (!GetRoot()) return FORMAT_ERROR; } @@ -1329,7 +1340,7 @@ CPDF_Parser::Error CPDF_Parser::StartLinearizedParse( if (m_pSecurityHandler && m_pSecurityHandler->IsMetadataEncrypted()) { if (CPDF_Reference* pMetadata = - ToReference(m_pDocument->GetRoot()->GetObjectFor("Metadata"))) + ToReference(GetRoot()->GetObjectFor("Metadata"))) m_MetadataObjnum = pMetadata->GetRefObjNum(); } return SUCCESS; |