diff options
-rw-r--r-- | core/fpdfapi/parser/cpdf_parser.cpp | 2 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_syntax_parser.cpp | 155 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_syntax_parser.h | 13 |
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; |