From d2608a87173f00cb80830d56b52eeb588055ba3a Mon Sep 17 00:00:00 2001 From: Artem Strygin Date: Fri, 1 Sep 2017 18:52:30 +0300 Subject: Move Parsing of indirect object logic into CPDF_SyntaxParser. Change-Id: I5473d6db3e6fc247d52a83b34424958dc20387f4 Reviewed-on: https://pdfium-review.googlesource.com/12150 Reviewed-by: dsinclair Commit-Queue: Art Snake --- core/fpdfapi/parser/cpdf_object.h | 2 +- core/fpdfapi/parser/cpdf_parser.cpp | 57 +++++++----------------------- core/fpdfapi/parser/cpdf_parser.h | 3 +- core/fpdfapi/parser/cpdf_syntax_parser.cpp | 43 ++++++++++++++++++++++ core/fpdfapi/parser/cpdf_syntax_parser.h | 10 ++++-- 5 files changed, 66 insertions(+), 49 deletions(-) diff --git a/core/fpdfapi/parser/cpdf_object.h b/core/fpdfapi/parser/cpdf_object.h index 82d7801cce..a07ba677e8 100644 --- a/core/fpdfapi/parser/cpdf_object.h +++ b/core/fpdfapi/parser/cpdf_object.h @@ -96,7 +96,7 @@ class CPDF_Object { friend class CPDF_Array; friend class CPDF_Dictionary; friend class CPDF_IndirectObjectHolder; - friend class CPDF_Parser; + friend class CPDF_SyntaxParser; friend class CPDF_Reference; friend class CPDF_Stream; diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp index fffa7f9b00..a9cad02f5e 100644 --- a/core/fpdfapi/parser/cpdf_parser.cpp +++ b/core/fpdfapi/parser/cpdf_parser.cpp @@ -1012,7 +1012,7 @@ bool CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, bool bMainXRef) { if (!pObject) return false; - uint32_t objnum = pObject->m_ObjNum; + uint32_t objnum = pObject->GetObjNum(); if (!objnum) return false; @@ -1258,58 +1258,24 @@ std::unique_ptr CPDF_Parser::ParseIndirectObjectAt( CPDF_IndirectObjectHolder* pObjList, FX_FILESIZE pos, uint32_t objnum) { - return ParseIndirectObjectAtInternal(pObjList, pos, objnum, false, nullptr); + return ParseIndirectObjectAtInternal( + pObjList, pos, objnum, CPDF_SyntaxParser::ParseType::kLoose, nullptr); } std::unique_ptr CPDF_Parser::ParseIndirectObjectAtInternal( CPDF_IndirectObjectHolder* pObjList, FX_FILESIZE pos, uint32_t objnum, - bool strict_parse, + CPDF_SyntaxParser::ParseType parse_type, FX_FILESIZE* pResultPos) { - FX_FILESIZE SavedPos = m_pSyntax->GetPos(); + const FX_FILESIZE saved_pos = m_pSyntax->GetPos(); m_pSyntax->SetPos(pos); - bool bIsNumber; - CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber); - if (!bIsNumber) { - m_pSyntax->SetPos(SavedPos); - return nullptr; - } - - uint32_t parser_objnum = FXSYS_atoui(word.c_str()); - if (objnum && parser_objnum != objnum) { - m_pSyntax->SetPos(SavedPos); - return nullptr; - } - - word = m_pSyntax->GetNextWord(&bIsNumber); - if (!bIsNumber) { - m_pSyntax->SetPos(SavedPos); - return nullptr; - } - - uint32_t parser_gennum = FXSYS_atoui(word.c_str()); - if (m_pSyntax->GetKeyword() != "obj") { - m_pSyntax->SetPos(SavedPos); - return nullptr; - } - - std::unique_ptr pObj = - strict_parse - ? m_pSyntax->GetObjectForStrict(pObjList, objnum, parser_gennum, true) - : m_pSyntax->GetObject(pObjList, objnum, parser_gennum, true); - + auto result = + m_pSyntax->GetIndirectObject(pObjList, objnum, true, parse_type); if (pResultPos) - *pResultPos = m_pSyntax->m_Pos; - - if (pObj) { - if (!objnum) - pObj->m_ObjNum = parser_objnum; - pObj->m_GenNum = parser_gennum; - } - - m_pSyntax->SetPos(SavedPos); - return pObj; + *pResultPos = m_pSyntax->GetPos(); + m_pSyntax->SetPos(saved_pos); + return result; } std::unique_ptr CPDF_Parser::ParseIndirectObjectAtByStrict( @@ -1317,7 +1283,8 @@ std::unique_ptr CPDF_Parser::ParseIndirectObjectAtByStrict( FX_FILESIZE pos, uint32_t objnum, FX_FILESIZE* pResultPos) { - return ParseIndirectObjectAtInternal(pObjList, pos, objnum, true, pResultPos); + return ParseIndirectObjectAtInternal( + pObjList, pos, objnum, CPDF_SyntaxParser::ParseType::kStrict, pResultPos); } uint32_t CPDF_Parser::GetFirstPageNo() const { diff --git a/core/fpdfapi/parser/cpdf_parser.h b/core/fpdfapi/parser/cpdf_parser.h index 0db2aa7ba1..b4d0bee329 100644 --- a/core/fpdfapi/parser/cpdf_parser.h +++ b/core/fpdfapi/parser/cpdf_parser.h @@ -13,6 +13,7 @@ #include #include +#include "core/fpdfapi/parser/cpdf_syntax_parser.h" #include "core/fxcrt/cfx_retain_ptr.h" #include "core/fxcrt/cfx_unowned_ptr.h" #include "core/fxcrt/fx_string.h" @@ -184,7 +185,7 @@ class CPDF_Parser { CPDF_IndirectObjectHolder* pObjList, FX_FILESIZE pos, uint32_t objnum, - bool strict_parse, + CPDF_SyntaxParser::ParseType parse_type, FX_FILESIZE* pResultPos); bool InitSyntaxParser( diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp index e3a23cf462..73932494c0 100644 --- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp +++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp @@ -529,6 +529,49 @@ std::unique_ptr CPDF_SyntaxParser::GetObjectForStrict( return result; } +std::unique_ptr CPDF_SyntaxParser::GetIndirectObject( + CPDF_IndirectObjectHolder* pObjList, + uint32_t objnum, + bool bDecrypt, + ParseType parse_type) { + const CPDF_ReadValidator::Session read_session(GetValidator().Get()); + const FX_FILESIZE saved_pos = GetPos(); + bool is_number = false; + CFX_ByteString word = GetNextWord(&is_number); + if (!is_number || word.IsEmpty()) { + SetPos(saved_pos); + return nullptr; + } + + uint32_t parser_objnum = FXSYS_atoui(word.c_str()); + if (objnum && parser_objnum != objnum) { + SetPos(saved_pos); + return nullptr; + } + + word = GetNextWord(&is_number); + if (!is_number || word.IsEmpty()) { + SetPos(saved_pos); + return nullptr; + } + + const uint32_t parser_gennum = FXSYS_atoui(word.c_str()); + if (GetKeyword() != "obj") { + SetPos(saved_pos); + return nullptr; + } + + std::unique_ptr pObj = + GetObjectInternal(pObjList, objnum, parser_gennum, bDecrypt, parse_type); + if (pObj) { + if (!objnum) + pObj->m_ObjNum = parser_objnum; + pObj->m_GenNum = parser_gennum; + } + + return GetValidator()->has_read_problems() ? nullptr : std::move(pObj); +} + 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 c95188acbe..88bbc5c9fa 100644 --- a/core/fpdfapi/parser/cpdf_syntax_parser.h +++ b/core/fpdfapi/parser/cpdf_syntax_parser.h @@ -23,6 +23,8 @@ class IFX_SeekableReadStream; class CPDF_SyntaxParser { public: + enum class ParseType { kStrict, kLoose }; + CPDF_SyntaxParser(); explicit CPDF_SyntaxParser(const CFX_WeakPtr& pPool); ~CPDF_SyntaxParser(); @@ -48,6 +50,12 @@ class CPDF_SyntaxParser { uint32_t gennum, bool bDecrypt); + std::unique_ptr GetIndirectObject( + CPDF_IndirectObjectHolder* pObjList, + uint32_t objnum, + bool bDecrypt, + ParseType parse_type); + CFX_ByteString GetKeyword(); void ToNextLine(); void ToNextWord(); @@ -95,8 +103,6 @@ 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, -- cgit v1.2.3