Add validator into CPDF_SyntaxParser.

Change-Id: I7fe8dcd8854e2f08b7b0ee53bde6c864108142ff
Reviewed-on: https://pdfium-review.googlesource.com/9571
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
index 5fa3372..979ccad 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 @@
 }
 
 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 @@
     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_Object> CPDF_SyntaxParser::GetObjectInternal(
+    CPDF_IndirectObjectHolder* pObjList,
+    uint32_t objnum,
+    uint32_t gennum,
+    bool bDecrypt) {
   CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth);
   if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth)
     return nullptr;
@@ -492,6 +508,17 @@
     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_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;
@@ -765,16 +792,25 @@
 void CPDF_SyntaxParser::InitParser(
     const CFX_RetainPtr<IFX_SeekableReadStream>& pFileAccess,
     uint32_t HeaderOffset) {
-  FX_Free(m_pFileBuf);
+  ASSERT(pFileAccess);
+  return InitParserWithValidator(
+      pdfium::MakeRetain<CPDF_ReadValidator>(pFileAccess, nullptr),
+      HeaderOffset);
+}
 
+void CPDF_SyntaxParser::InitParserWithValidator(
+    const CFX_RetainPtr<CPDF_ReadValidator>& 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<uint32_t>(m_FileLen)));
+  validator->ReadBlock(m_pFileBuf, 0,
+                       std::min(m_BufSize, static_cast<uint32_t>(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 d522b4a..d3bca11 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.h
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.h
@@ -18,6 +18,7 @@
 class CPDF_Dictionary;
 class CPDF_IndirectObjectHolder;
 class CPDF_Object;
+class CPDF_ReadValidator;
 class CPDF_Stream;
 class IFX_SeekableReadStream;
 
@@ -30,6 +31,10 @@
   void InitParser(const CFX_RetainPtr<IFX_SeekableReadStream>& pFileAccess,
                   uint32_t HeaderOffset);
 
+  void InitParserWithValidator(
+      const CFX_RetainPtr<CPDF_ReadValidator>& 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 @@
 
   CFX_RetainPtr<IFX_SeekableReadStream> GetFileAccess() const;
 
+  const CFX_RetainPtr<CPDF_ReadValidator>& GetValidator() const {
+    return m_pFileAccess;
+  }
+
  private:
   friend class CPDF_Parser;
   friend class CPDF_DataAvail;
@@ -86,9 +95,20 @@
            static_cast<FX_FILESIZE>(m_BufOffset + m_BufSize) <= pos;
   }
 
+  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);
+
   FX_FILESIZE m_Pos;
   uint32_t m_MetadataObjnum;
-  CFX_RetainPtr<IFX_SeekableReadStream> m_pFileAccess;
+  CFX_RetainPtr<CPDF_ReadValidator> m_pFileAccess;
   FX_FILESIZE m_HeaderOffset;
   FX_FILESIZE m_FileLen;
   uint8_t* m_pFileBuf;