summaryrefslogtreecommitdiff
path: root/core/fpdfapi/parser/cpdf_parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/fpdfapi/parser/cpdf_parser.cpp')
-rw-r--r--core/fpdfapi/parser/cpdf_parser.cpp103
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;