summaryrefslogtreecommitdiff
path: root/core/fpdfapi
diff options
context:
space:
mode:
Diffstat (limited to 'core/fpdfapi')
-rw-r--r--core/fpdfapi/parser/cpdf_parser.cpp2
-rw-r--r--core/fpdfapi/parser/cpdf_syntax_parser.cpp155
-rw-r--r--core/fpdfapi/parser/cpdf_syntax_parser.h13
3 files changed, 35 insertions, 135 deletions
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index 3184d88943..167c1f438b 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -1296,7 +1296,7 @@ std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObjectAtInternal(
std::unique_ptr<CPDF_Object> pObj =
strict_parse
- ? m_pSyntax->GetObjectForStrict(pObjList, objnum, parser_gennum)
+ ? m_pSyntax->GetObjectForStrict(pObjList, objnum, parser_gennum, true)
: m_pSyntax->GetObject(pObjList, objnum, parser_gennum, true);
if (pResultPos)
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
index 979ccad712..7592438258 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
@@ -376,7 +376,8 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObject(
uint32_t gennum,
bool bDecrypt) {
const CPDF_ReadValidator::Session read_session(GetValidator().Get());
- auto result = GetObjectInternal(pObjList, objnum, gennum, bDecrypt);
+ auto result =
+ GetObjectInternal(pObjList, objnum, gennum, bDecrypt, ParseType::kLoose);
if (GetValidator()->has_read_problems())
return nullptr;
return result;
@@ -386,7 +387,8 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectInternal(
CPDF_IndirectObjectHolder* pObjList,
uint32_t objnum,
uint32_t gennum,
- bool bDecrypt) {
+ bool bDecrypt,
+ ParseType parse_type) {
CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth);
if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth)
return nullptr;
@@ -432,12 +434,14 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectInternal(
return pdfium::MakeUnique<CPDF_String>(m_pPool, str, true);
}
if (word == "[") {
- std::unique_ptr<CPDF_Array> pArray = pdfium::MakeUnique<CPDF_Array>();
+ auto pArray = pdfium::MakeUnique<CPDF_Array>();
while (std::unique_ptr<CPDF_Object> pObj =
GetObject(pObjList, objnum, gennum, true)) {
pArray->Add(std::move(pObj));
}
- return std::move(pArray);
+ return (parse_type == ParseType::kLoose || m_WordBuffer[0] == ']')
+ ? std::move(pArray)
+ : nullptr;
}
if (word[0] == '/') {
return pdfium::MakeUnique<CPDF_Name>(
@@ -445,7 +449,6 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectInternal(
PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)));
}
if (word == "<<") {
- int32_t nKeys = 0;
FX_FILESIZE dwSignValuePos = 0;
std::unique_ptr<CPDF_Dictionary> pDict =
pdfium::MakeUnique<CPDF_Dictionary>(m_pPool);
@@ -465,26 +468,33 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectInternal(
if (key[0] != '/')
continue;
- ++nKeys;
key = PDF_NameDecode(key);
- if (key.IsEmpty())
- continue;
-
if (key == "/Contents")
dwSignValuePos = m_Pos;
+ if (key.IsEmpty() && parse_type == ParseType::kLoose)
+ continue;
+
std::unique_ptr<CPDF_Object> pObj =
GetObject(pObjList, objnum, gennum, true);
- if (!pObj)
- continue;
+ if (!pObj) {
+ if (parse_type == ParseType::kLoose)
+ continue;
+
+ ToNextLine();
+ return nullptr;
+ }
- CFX_ByteString keyNoSlash(key.raw_str() + 1, key.GetLength() - 1);
- pDict->SetFor(keyNoSlash, std::move(pObj));
+ if (!key.IsEmpty()) {
+ CFX_ByteString keyNoSlash(key.raw_str() + 1, key.GetLength() - 1);
+ pDict->SetFor(keyNoSlash, std::move(pObj));
+ }
}
// Only when this is a signature dictionary and has contents, we reset the
// contents to the un-decrypted form.
- if (pDict->IsSignatureDict() && dwSignValuePos) {
+ if (m_pCryptoHandler && bDecrypt && pDict->IsSignatureDict() &&
+ dwSignValuePos) {
CFX_AutoRestorer<FX_FILESIZE> save_pos(&m_Pos);
m_Pos = dwSignValuePos;
pDict->SetFor("Contents", GetObject(pObjList, objnum, gennum, false));
@@ -507,125 +517,16 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectInternal(
std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectForStrict(
CPDF_IndirectObjectHolder* pObjList,
uint32_t objnum,
- uint32_t gennum) {
+ uint32_t gennum,
+ bool bDecrypt) {
const CPDF_ReadValidator::Session read_session(GetValidator().Get());
- auto result = GetObjectForStrictInternal(pObjList, objnum, gennum);
+ auto result =
+ GetObjectInternal(pObjList, objnum, gennum, bDecrypt, ParseType::kStrict);
if (GetValidator()->has_read_problems())
return nullptr;
return result;
}
-std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectForStrictInternal(
- CPDF_IndirectObjectHolder* pObjList,
- uint32_t objnum,
- uint32_t gennum) {
- CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth);
- if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth)
- return nullptr;
-
- FX_FILESIZE SavedObjPos = m_Pos;
- bool bIsNumber;
- CFX_ByteString word = GetNextWord(&bIsNumber);
- if (word.GetLength() == 0)
- return nullptr;
-
- if (bIsNumber) {
- FX_FILESIZE SavedPos = m_Pos;
- CFX_ByteString nextword = GetNextWord(&bIsNumber);
- if (bIsNumber) {
- CFX_ByteString nextword2 = GetNextWord(nullptr);
- if (nextword2 == "R") {
- uint32_t refnum = FXSYS_atoui(word.c_str());
- if (refnum == CPDF_Object::kInvalidObjNum)
- return nullptr;
- return pdfium::MakeUnique<CPDF_Reference>(pObjList, refnum);
- }
- }
- m_Pos = SavedPos;
- return pdfium::MakeUnique<CPDF_Number>(word.AsStringC());
- }
-
- if (word == "true" || word == "false")
- return pdfium::MakeUnique<CPDF_Boolean>(word == "true");
-
- if (word == "null")
- return pdfium::MakeUnique<CPDF_Null>();
-
- if (word == "(") {
- CFX_ByteString str = ReadString();
- if (m_pCryptoHandler)
- str = m_pCryptoHandler->Decrypt(objnum, gennum, str);
- return pdfium::MakeUnique<CPDF_String>(m_pPool, str, false);
- }
- if (word == "<") {
- CFX_ByteString str = ReadHexString();
- if (m_pCryptoHandler)
- str = m_pCryptoHandler->Decrypt(objnum, gennum, str);
- return pdfium::MakeUnique<CPDF_String>(m_pPool, str, true);
- }
- if (word == "[") {
- auto pArray = pdfium::MakeUnique<CPDF_Array>();
- while (std::unique_ptr<CPDF_Object> pObj =
- GetObject(pObjList, objnum, gennum, true)) {
- pArray->Add(std::move(pObj));
- }
- return m_WordBuffer[0] == ']' ? std::move(pArray) : nullptr;
- }
- if (word[0] == '/') {
- return pdfium::MakeUnique<CPDF_Name>(
- m_pPool,
- PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)));
- }
- if (word == "<<") {
- std::unique_ptr<CPDF_Dictionary> pDict =
- pdfium::MakeUnique<CPDF_Dictionary>(m_pPool);
- while (1) {
- FX_FILESIZE SavedPos = m_Pos;
- CFX_ByteString key = GetNextWord(nullptr);
- if (key.IsEmpty())
- return nullptr;
-
- if (key == ">>")
- break;
-
- if (key == "endobj") {
- m_Pos = SavedPos;
- break;
- }
- if (key[0] != '/')
- continue;
-
- key = PDF_NameDecode(key);
- std::unique_ptr<CPDF_Object> obj(
- GetObject(pObjList, objnum, gennum, true));
- if (!obj) {
- uint8_t ch;
- while (GetNextChar(ch) && ch != 0x0A && ch != 0x0D) {
- continue;
- }
- return nullptr;
- }
-
- if (key.GetLength() > 1) {
- pDict->SetFor(CFX_ByteString(key.c_str() + 1, key.GetLength() - 1),
- std::move(obj));
- }
- }
-
- FX_FILESIZE SavedPos = m_Pos;
- CFX_ByteString nextword = GetNextWord(nullptr);
- if (nextword != "stream") {
- m_Pos = SavedPos;
- return std::move(pDict);
- }
- return ReadStream(std::move(pDict), objnum, gennum);
- }
- if (word == ">>")
- m_Pos = SavedObjPos;
-
- return nullptr;
-}
-
unsigned int CPDF_SyntaxParser::ReadEOLMarkers(FX_FILESIZE pos) {
unsigned char byte1 = 0;
unsigned char byte2 = 0;
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.h b/core/fpdfapi/parser/cpdf_syntax_parser.h
index d3bca11e59..25c7403961 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.h
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.h
@@ -46,7 +46,8 @@ class CPDF_SyntaxParser {
std::unique_ptr<CPDF_Object> GetObjectForStrict(
CPDF_IndirectObjectHolder* pObjList,
uint32_t objnum,
- uint32_t gennum);
+ uint32_t gennum,
+ bool bDecrypt);
CFX_ByteString GetKeyword();
void ToNextLine();
@@ -95,16 +96,14 @@ class CPDF_SyntaxParser {
static_cast<FX_FILESIZE>(m_BufOffset + m_BufSize) <= pos;
}
+ enum class ParseType { kStrict, kLoose };
+
std::unique_ptr<CPDF_Object> GetObjectInternal(
CPDF_IndirectObjectHolder* pObjList,
uint32_t objnum,
uint32_t gennum,
- bool bDecrypt);
-
- std::unique_ptr<CPDF_Object> GetObjectForStrictInternal(
- CPDF_IndirectObjectHolder* pObjList,
- uint32_t objnum,
- uint32_t gennum);
+ bool bDecrypt,
+ ParseType parse_type);
FX_FILESIZE m_Pos;
uint32_t m_MetadataObjnum;