From 31d706bd8122830a15c574ba461e8f1a41427b9c Mon Sep 17 00:00:00 2001 From: Artem Strygin Date: Thu, 3 Aug 2017 16:08:40 +0300 Subject: Add validator into CPDF_SyntaxParser. Change-Id: I7fe8dcd8854e2f08b7b0ee53bde6c864108142ff Reviewed-on: https://pdfium-review.googlesource.com/9571 Reviewed-by: Lei Zhang --- core/fpdfapi/parser/cpdf_syntax_parser.cpp | 48 ++++++++++++++++++++++++++---- core/fpdfapi/parser/cpdf_syntax_parser.h | 22 +++++++++++++- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp index 5fa3372d50..979ccad712 100644 --- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp +++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp @@ -19,6 +19,7 @@ #include "core/fpdfapi/parser/cpdf_name.h" #include "core/fpdfapi/parser/cpdf_null.h" #include "core/fpdfapi/parser/cpdf_number.h" +#include "core/fpdfapi/parser/cpdf_read_validator.h" #include "core/fpdfapi/parser/cpdf_reference.h" #include "core/fpdfapi/parser/cpdf_stream.h" #include "core/fpdfapi/parser/cpdf_string.h" @@ -358,8 +359,11 @@ void CPDF_SyntaxParser::ToNextWord() { } CFX_ByteString CPDF_SyntaxParser::GetNextWord(bool* bIsNumber) { + const CPDF_ReadValidator::Session read_session(GetValidator().Get()); GetNextWordInternal(bIsNumber); - return CFX_ByteString((const char*)m_WordBuffer, m_WordSize); + return GetValidator()->has_read_problems() + ? CFX_ByteString() + : CFX_ByteString((const char*)m_WordBuffer, m_WordSize); } CFX_ByteString CPDF_SyntaxParser::GetKeyword() { @@ -371,6 +375,18 @@ std::unique_ptr CPDF_SyntaxParser::GetObject( uint32_t objnum, uint32_t gennum, bool bDecrypt) { + const CPDF_ReadValidator::Session read_session(GetValidator().Get()); + auto result = GetObjectInternal(pObjList, objnum, gennum, bDecrypt); + if (GetValidator()->has_read_problems()) + return nullptr; + return result; +} + +std::unique_ptr CPDF_SyntaxParser::GetObjectInternal( + CPDF_IndirectObjectHolder* pObjList, + uint32_t objnum, + uint32_t gennum, + bool bDecrypt) { CFX_AutoRestorer restorer(&s_CurrentRecursionDepth); if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) return nullptr; @@ -492,6 +508,17 @@ std::unique_ptr CPDF_SyntaxParser::GetObjectForStrict( CPDF_IndirectObjectHolder* pObjList, uint32_t objnum, uint32_t gennum) { + const CPDF_ReadValidator::Session read_session(GetValidator().Get()); + auto result = GetObjectForStrictInternal(pObjList, objnum, gennum); + 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; @@ -765,16 +792,25 @@ std::unique_ptr CPDF_SyntaxParser::ReadStream( void CPDF_SyntaxParser::InitParser( const CFX_RetainPtr& pFileAccess, uint32_t HeaderOffset) { - FX_Free(m_pFileBuf); + ASSERT(pFileAccess); + return InitParserWithValidator( + pdfium::MakeRetain(pFileAccess, nullptr), + HeaderOffset); +} +void CPDF_SyntaxParser::InitParserWithValidator( + const CFX_RetainPtr& validator, + uint32_t HeaderOffset) { + ASSERT(validator); + FX_Free(m_pFileBuf); m_pFileBuf = FX_Alloc(uint8_t, m_BufSize); m_HeaderOffset = HeaderOffset; - m_FileLen = pFileAccess->GetSize(); + m_FileLen = validator->GetSize(); m_Pos = 0; - m_pFileAccess = pFileAccess; + m_pFileAccess = validator; m_BufOffset = 0; - pFileAccess->ReadBlock(m_pFileBuf, 0, - std::min(m_BufSize, static_cast(m_FileLen))); + validator->ReadBlock(m_pFileBuf, 0, + std::min(m_BufSize, static_cast(m_FileLen))); } uint32_t CPDF_SyntaxParser::GetDirectNum() { diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.h b/core/fpdfapi/parser/cpdf_syntax_parser.h index d522b4ae7a..d3bca11e59 100644 --- a/core/fpdfapi/parser/cpdf_syntax_parser.h +++ b/core/fpdfapi/parser/cpdf_syntax_parser.h @@ -18,6 +18,7 @@ class CPDF_CryptoHandler; class CPDF_Dictionary; class CPDF_IndirectObjectHolder; class CPDF_Object; +class CPDF_ReadValidator; class CPDF_Stream; class IFX_SeekableReadStream; @@ -30,6 +31,10 @@ class CPDF_SyntaxParser { void InitParser(const CFX_RetainPtr& pFileAccess, uint32_t HeaderOffset); + void InitParserWithValidator( + const CFX_RetainPtr& pValidator, + uint32_t HeaderOffset); + FX_FILESIZE GetPos() const { return m_Pos; } void SetPos(FX_FILESIZE pos) { m_Pos = std::min(pos, m_FileLen); } @@ -55,6 +60,10 @@ class CPDF_SyntaxParser { CFX_RetainPtr GetFileAccess() const; + const CFX_RetainPtr& GetValidator() const { + return m_pFileAccess; + } + private: friend class CPDF_Parser; friend class CPDF_DataAvail; @@ -86,9 +95,20 @@ class CPDF_SyntaxParser { static_cast(m_BufOffset + m_BufSize) <= pos; } + 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); + FX_FILESIZE m_Pos; uint32_t m_MetadataObjnum; - CFX_RetainPtr m_pFileAccess; + CFX_RetainPtr m_pFileAccess; FX_FILESIZE m_HeaderOffset; FX_FILESIZE m_FileLen; uint8_t* m_pFileBuf; -- cgit v1.2.3