From a8efb5183422e07210771c975e5ae7655957cc77 Mon Sep 17 00:00:00 2001 From: Artem Strygin Date: Mon, 28 Aug 2017 14:13:00 +0300 Subject: Unify CPDF_SyntaxParser::GetObjectXXX methods. Merge CPDF_SyntaxParser::GetObject and CPDF_SyntaxParser::GetObjectForStrict. Change-Id: Ic9ff51e24ee981c268239847e3cca1c6f6a6f269 Reviewed-on: https://pdfium-review.googlesource.com/10511 Commit-Queue: dsinclair Reviewed-by: dsinclair --- core/fpdfapi/parser/cpdf_parser.cpp | 2 +- core/fpdfapi/parser/cpdf_syntax_parser.cpp | 155 ++++++----------------------- 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_Parser::ParseIndirectObjectAtInternal( std::unique_ptr 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_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_SyntaxParser::GetObjectInternal( CPDF_IndirectObjectHolder* pObjList, uint32_t objnum, uint32_t gennum, - bool bDecrypt) { + bool bDecrypt, + ParseType parse_type) { CFX_AutoRestorer restorer(&s_CurrentRecursionDepth); if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) return nullptr; @@ -432,12 +434,14 @@ std::unique_ptr CPDF_SyntaxParser::GetObjectInternal( return pdfium::MakeUnique(m_pPool, str, true); } if (word == "[") { - std::unique_ptr pArray = pdfium::MakeUnique(); + auto pArray = pdfium::MakeUnique(); while (std::unique_ptr 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( @@ -445,7 +449,6 @@ std::unique_ptr 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 pDict = pdfium::MakeUnique(m_pPool); @@ -465,26 +468,33 @@ std::unique_ptr 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 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 save_pos(&m_Pos); m_Pos = dwSignValuePos; pDict->SetFor("Contents", GetObject(pObjList, objnum, gennum, false)); @@ -507,125 +517,16 @@ std::unique_ptr CPDF_SyntaxParser::GetObjectInternal( std::unique_ptr 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_SyntaxParser::GetObjectForStrictInternal( - CPDF_IndirectObjectHolder* pObjList, - uint32_t objnum, - uint32_t gennum) { - CFX_AutoRestorer 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(pObjList, refnum); - } - } - m_Pos = SavedPos; - return pdfium::MakeUnique(word.AsStringC()); - } - - if (word == "true" || word == "false") - return pdfium::MakeUnique(word == "true"); - - if (word == "null") - return pdfium::MakeUnique(); - - if (word == "(") { - CFX_ByteString str = ReadString(); - if (m_pCryptoHandler) - str = m_pCryptoHandler->Decrypt(objnum, gennum, str); - return pdfium::MakeUnique(m_pPool, str, false); - } - if (word == "<") { - CFX_ByteString str = ReadHexString(); - if (m_pCryptoHandler) - str = m_pCryptoHandler->Decrypt(objnum, gennum, str); - return pdfium::MakeUnique(m_pPool, str, true); - } - if (word == "[") { - auto pArray = pdfium::MakeUnique(); - while (std::unique_ptr 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( - m_pPool, - PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); - } - if (word == "<<") { - std::unique_ptr pDict = - pdfium::MakeUnique(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 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 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(m_BufOffset + m_BufSize) <= pos; } + enum class ParseType { kStrict, kLoose }; + std::unique_ptr GetObjectInternal( CPDF_IndirectObjectHolder* pObjList, uint32_t objnum, uint32_t gennum, - bool bDecrypt); - - std::unique_ptr GetObjectForStrictInternal( - CPDF_IndirectObjectHolder* pObjList, - uint32_t objnum, - uint32_t gennum); + bool bDecrypt, + ParseType parse_type); FX_FILESIZE m_Pos; uint32_t m_MetadataObjnum; -- cgit v1.2.3