// Copyright 2016 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fpdfapi/parser/cpdf_syntax_parser.h"

#include <ctype.h>

#include <algorithm>
#include <utility>

#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_boolean.h"
#include "core/fpdfapi/parser/cpdf_crypto_handler.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#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"
#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fxcrt/autorestorer.h"
#include "core/fxcrt/cfx_read_only_vector_stream.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/check_op.h"
#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fixed_size_data_vector.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_memcpy_wrappers.h"
#include "core/fxcrt/fx_safe_types.h"

namespace {

enum class ReadStatus {
  kNormal,
  kBackslash,
  kOctal,
  kFinishOctal,
  kCarriageReturn
};

class ReadableSubStream final : public IFX_SeekableReadStream {
 public:
  ReadableSubStream(RetainPtr<IFX_SeekableReadStream> pFileRead,
                    FX_FILESIZE part_offset,
                    FX_FILESIZE part_size)
      : m_pFileRead(std::move(pFileRead)),
        m_PartOffset(part_offset),
        m_PartSize(part_size) {}

  ~ReadableSubStream() override = default;

  // IFX_SeekableReadStream overrides:
  bool ReadBlockAtOffset(pdfium::span<uint8_t> buffer,
                         FX_FILESIZE offset) override {
    FX_SAFE_FILESIZE safe_end = offset;
    safe_end += buffer.size();
    // Check that requested range is valid, to prevent calling of ReadBlock
    // of original m_pFileRead with incorrect params.
    if (!safe_end.IsValid() || safe_end.ValueOrDie() > m_PartSize)
      return false;

    return m_pFileRead->ReadBlockAtOffset(buffer, m_PartOffset + offset);
  }

  FX_FILESIZE GetSize() override { return m_PartSize; }

 private:
  RetainPtr<IFX_SeekableReadStream> m_pFileRead;
  FX_FILESIZE m_PartOffset;
  FX_FILESIZE m_PartSize;
};

}  // namespace

// static
int CPDF_SyntaxParser::s_CurrentRecursionDepth = 0;

// static
std::unique_ptr<CPDF_SyntaxParser> CPDF_SyntaxParser::CreateForTesting(
    RetainPtr<IFX_SeekableReadStream> pFileAccess,
    FX_FILESIZE HeaderOffset) {
  return std::make_unique<CPDF_SyntaxParser>(
      pdfium::MakeRetain<CPDF_ReadValidator>(std::move(pFileAccess), nullptr),
      HeaderOffset);
}

CPDF_SyntaxParser::CPDF_SyntaxParser(
    RetainPtr<IFX_SeekableReadStream> pFileAccess)
    : CPDF_SyntaxParser(
          pdfium::MakeRetain<CPDF_ReadValidator>(std::move(pFileAccess),
                                                 nullptr),
          0) {}

CPDF_SyntaxParser::CPDF_SyntaxParser(RetainPtr<CPDF_ReadValidator> validator,
                                     FX_FILESIZE HeaderOffset)
    : m_pFileAccess(std::move(validator)),
      m_HeaderOffset(HeaderOffset),
      m_FileLen(m_pFileAccess->GetSize()) {
  DCHECK(m_HeaderOffset <= m_FileLen);
}

CPDF_SyntaxParser::~CPDF_SyntaxParser() = default;

bool CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, uint8_t& ch) {
  AutoRestorer<FX_FILESIZE> save_pos(&m_Pos);
  m_Pos = pos;
  return GetNextChar(ch);
}

bool CPDF_SyntaxParser::ReadBlockAt(FX_FILESIZE read_pos) {
  if (read_pos >= m_FileLen)
    return false;
  size_t read_size = m_ReadBufferSize;
  FX_SAFE_FILESIZE safe_end = read_pos;
  safe_end += read_size;
  if (!safe_end.IsValid() || safe_end.ValueOrDie() > m_FileLen)
    read_size = m_FileLen - read_pos;

  m_pFileBuf.resize(read_size);
  if (!m_pFileAccess->ReadBlockAtOffset(m_pFileBuf, read_pos)) {
    m_pFileBuf.clear();
    return false;
  }

  m_BufOffset = read_pos;
  return true;
}

bool CPDF_SyntaxParser::GetNextChar(uint8_t& ch) {
  FX_FILESIZE pos = m_Pos + m_HeaderOffset;
  if (pos >= m_FileLen)
    return false;

  if (!IsPositionRead(pos) && !ReadBlockAt(pos))
    return false;

  ch = m_pFileBuf[pos - m_BufOffset];
  m_Pos++;
  return true;
}

FX_FILESIZE CPDF_SyntaxParser::GetDocumentSize() const {
  return m_FileLen - m_HeaderOffset;
}

bool CPDF_SyntaxParser::GetCharAtBackward(FX_FILESIZE pos, uint8_t* ch) {
  pos += m_HeaderOffset;
  if (pos >= m_FileLen)
    return false;

  if (!IsPositionRead(pos)) {
    FX_FILESIZE block_start = 0;
    if (pos >= CPDF_Stream::kFileBufSize)
      block_start = pos - CPDF_Stream::kFileBufSize + 1;
    if (!ReadBlockAt(block_start) || !IsPositionRead(pos))
      return false;
  }
  *ch = m_pFileBuf[pos - m_BufOffset];
  return true;
}

bool CPDF_SyntaxParser::ReadBlock(pdfium::span<uint8_t> buffer) {
  if (!m_pFileAccess->ReadBlockAtOffset(buffer, m_Pos + m_HeaderOffset))
    return false;
  m_Pos += buffer.size();
  return true;
}

CPDF_SyntaxParser::WordType CPDF_SyntaxParser::GetNextWordInternal() {
  m_WordSize = 0;
  WordType word_type = WordType::kNumber;

  ToNextWord();
  uint8_t ch;
  if (!GetNextChar(ch))
    return word_type;

  if (PDFCharIsDelimiter(ch)) {
    word_type = WordType::kWord;

    m_WordBuffer[m_WordSize++] = ch;
    if (ch == '/') {
      while (true) {
        if (!GetNextChar(ch))
          return word_type;

        if (!PDFCharIsOther(ch) && !PDFCharIsNumeric(ch)) {
          m_Pos--;
          return word_type;
        }

        if (m_WordSize < sizeof(m_WordBuffer) - 1)
          m_WordBuffer[m_WordSize++] = ch;
      }
    } else if (ch == '<') {
      if (!GetNextChar(ch))
        return word_type;

      if (ch == '<')
        m_WordBuffer[m_WordSize++] = ch;
      else
        m_Pos--;
    } else if (ch == '>') {
      if (!GetNextChar(ch))
        return word_type;

      if (ch == '>')
        m_WordBuffer[m_WordSize++] = ch;
      else
        m_Pos--;
    }
    return word_type;
  }

  while (true) {
    if (m_WordSize < sizeof(m_WordBuffer) - 1)
      m_WordBuffer[m_WordSize++] = ch;

    if (!PDFCharIsNumeric(ch))
      word_type = WordType::kWord;

    if (!GetNextChar(ch))
      return word_type;

    if (PDFCharIsDelimiter(ch) || PDFCharIsWhitespace(ch)) {
      m_Pos--;
      break;
    }
  }
  return word_type;
}

ByteString CPDF_SyntaxParser::ReadString() {
  uint8_t ch;
  if (!GetNextChar(ch))
    return ByteString();

  ByteString buf;
  int32_t parlevel = 0;
  ReadStatus status = ReadStatus::kNormal;
  int32_t iEscCode = 0;
  while (true) {
    switch (status) {
      case ReadStatus::kNormal:
        if (ch == ')') {
          if (parlevel == 0)
            return ByteString(buf);
          parlevel--;
        } else if (ch == '(') {
          parlevel++;
        }
        if (ch == '\\')
          status = ReadStatus::kBackslash;
        else
          buf += static_cast<char>(ch);
        break;
      case ReadStatus::kBackslash:
        if (FXSYS_IsOctalDigit(ch)) {
          iEscCode = FXSYS_DecimalCharToInt(static_cast<wchar_t>(ch));
          status = ReadStatus::kOctal;
          break;
        }
        if (ch == '\r') {
          status = ReadStatus::kCarriageReturn;
          break;
        }
        if (ch == 'n') {
          buf += '\n';
        } else if (ch == 'r') {
          buf += '\r';
        } else if (ch == 't') {
          buf += '\t';
        } else if (ch == 'b') {
          buf += '\b';
        } else if (ch == 'f') {
          buf += '\f';
        } else if (ch != '\n') {
          buf += static_cast<char>(ch);
        }
        status = ReadStatus::kNormal;
        break;
      case ReadStatus::kOctal:
        if (FXSYS_IsOctalDigit(ch)) {
          iEscCode =
              iEscCode * 8 + FXSYS_DecimalCharToInt(static_cast<wchar_t>(ch));
          status = ReadStatus::kFinishOctal;
        } else {
          buf += static_cast<char>(iEscCode);
          status = ReadStatus::kNormal;
          continue;
        }
        break;
      case ReadStatus::kFinishOctal:
        status = ReadStatus::kNormal;
        if (FXSYS_IsOctalDigit(ch)) {
          iEscCode =
              iEscCode * 8 + FXSYS_DecimalCharToInt(static_cast<wchar_t>(ch));
          buf += static_cast<char>(iEscCode);
        } else {
          buf += static_cast<char>(iEscCode);
          continue;
        }
        break;
      case ReadStatus::kCarriageReturn:
        status = ReadStatus::kNormal;
        if (ch != '\n')
          continue;
        break;
    }

    if (!GetNextChar(ch))
      break;
  }

  GetNextChar(ch);
  return buf;
}

DataVector<uint8_t> CPDF_SyntaxParser::ReadHexString() {
  uint8_t ch;
  if (!GetNextChar(ch)) {
    return DataVector<uint8_t>();
  }

  DataVector<uint8_t> buf;
  bool bFirst = true;
  uint8_t code = 0;
  while (true) {
    if (ch == '>')
      break;

    if (isxdigit(ch)) {
      int val = FXSYS_HexCharToInt(ch);
      if (bFirst) {
        code = val * 16;
      } else {
        code += val;
        buf.push_back(code);
      }
      bFirst = !bFirst;
    }

    if (!GetNextChar(ch)) {
      break;
    }
  }
  if (!bFirst) {
    buf.push_back(code);
  }

  return buf;
}

void CPDF_SyntaxParser::ToNextLine() {
  uint8_t ch;
  while (GetNextChar(ch)) {
    if (ch == '\n')
      break;

    if (ch == '\r') {
      GetNextChar(ch);
      if (ch != '\n')
        --m_Pos;
      break;
    }
  }
}

void CPDF_SyntaxParser::ToNextWord() {
  if (m_TrailerEnds) {
    RecordingToNextWord();
    return;
  }

  uint8_t ch;
  if (!GetNextChar(ch))
    return;

  while (true) {
    while (PDFCharIsWhitespace(ch)) {
      if (!GetNextChar(ch))
        return;
    }

    if (ch != '%')
      break;

    while (true) {
      if (!GetNextChar(ch))
        return;
      if (PDFCharIsLineEnding(ch))
        break;
    }
  }
  m_Pos--;
}

// A state machine which goes % -> E -> O -> F -> line ending.
enum class EofState {
  kInitial = 0,
  kNonPercent,
  kPercent,
  kE,
  kO,
  kF,
  kInvalid,
};

void CPDF_SyntaxParser::RecordingToNextWord() {
  DCHECK(m_TrailerEnds);

  EofState eof_state = EofState::kInitial;
  // Find the first character which is neither whitespace, nor part of a
  // comment.
  while (true) {
    uint8_t ch;
    if (!GetNextChar(ch))
      return;
    switch (eof_state) {
      case EofState::kInitial:
        if (!PDFCharIsWhitespace(ch))
          eof_state = ch == '%' ? EofState::kPercent : EofState::kNonPercent;
        break;
      case EofState::kNonPercent:
        break;
      case EofState::kPercent:
        if (ch == 'E')
          eof_state = EofState::kE;
        else if (ch != '%')
          eof_state = EofState::kInvalid;
        break;
      case EofState::kE:
        eof_state = ch == 'O' ? EofState::kO : EofState::kInvalid;
        break;
      case EofState::kO:
        eof_state = ch == 'F' ? EofState::kF : EofState::kInvalid;
        break;
      case EofState::kF:
        if (ch == '\r') {
          // See if \r has to be combined with a \n that follows it
          // immediately.
          if (GetNextChar(ch) && ch != '\n') {
            ch = '\r';
            m_Pos--;
          }
        }
        // If we now have a \r, that's not followed by a \n, so both are OK.
        if (ch == '\r' || ch == '\n')
          m_TrailerEnds->push_back(m_Pos);
        eof_state = EofState::kInvalid;
        break;
      case EofState::kInvalid:
        break;
    }
    if (PDFCharIsLineEnding(ch))
      eof_state = EofState::kInitial;
    if (eof_state == EofState::kNonPercent)
      break;
  }
  m_Pos--;
}

CPDF_SyntaxParser::WordResult CPDF_SyntaxParser::GetNextWord() {
  CPDF_ReadValidator::ScopedSession read_session(GetValidator());
  WordType word_type = GetNextWordInternal();
  ByteString word;
  if (!GetValidator()->has_read_problems())
    word = ByteString(m_WordBuffer.data(), m_WordSize);
  return {word, word_type == WordType::kNumber};
}

ByteString CPDF_SyntaxParser::PeekNextWord() {
  AutoRestorer<FX_FILESIZE> save_pos(&m_Pos);
  return GetNextWord().word;
}

ByteString CPDF_SyntaxParser::GetKeyword() {
  return GetNextWord().word;
}

void CPDF_SyntaxParser::SetPos(FX_FILESIZE pos) {
  DCHECK_GE(pos, 0);
  m_Pos = std::min(pos, m_FileLen);
}

RetainPtr<CPDF_Object> CPDF_SyntaxParser::GetObjectBody(
    CPDF_IndirectObjectHolder* pObjList) {
  CPDF_ReadValidator::ScopedSession read_session(GetValidator());
  auto result = GetObjectBodyInternal(pObjList, ParseType::kLoose);
  if (GetValidator()->has_read_problems())
    return nullptr;
  return result;
}

RetainPtr<CPDF_Object> CPDF_SyntaxParser::GetObjectBodyInternal(
    CPDF_IndirectObjectHolder* pObjList,
    ParseType parse_type) {
  AutoRestorer<int> depth_restorer(&s_CurrentRecursionDepth);
  if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth)
    return nullptr;

  FX_FILESIZE SavedObjPos = m_Pos;
  WordResult word_result = GetNextWord();
  const ByteString& word = word_result.word;
  if (word.IsEmpty())
    return nullptr;

  if (word_result.is_number) {
    AutoRestorer<FX_FILESIZE> pos_restorer(&m_Pos);
    WordResult nextword = GetNextWord();
    if (!nextword.is_number)
      return pdfium::MakeRetain<CPDF_Number>(word.AsStringView());

    WordResult nextword2 = GetNextWord();
    if (nextword2.word != "R")
      return pdfium::MakeRetain<CPDF_Number>(word.AsStringView());

    pos_restorer.AbandonRestoration();
    uint32_t refnum = FXSYS_atoui(word.c_str());
    if (refnum == CPDF_Object::kInvalidObjNum)
      return nullptr;

    return pdfium::MakeRetain<CPDF_Reference>(pObjList, refnum);
  }

  if (word == "true" || word == "false")
    return pdfium::MakeRetain<CPDF_Boolean>(word == "true");

  if (word == "null")
    return pdfium::MakeRetain<CPDF_Null>();

  if (word == "(") {
    return pdfium::MakeRetain<CPDF_String>(m_pPool, ReadString());
  }
  if (word == "<") {
    return pdfium::MakeRetain<CPDF_String>(m_pPool, ReadHexString(),
                                           CPDF_String::DataType::kIsHex);
  }
  if (word == "[") {
    auto pArray = pdfium::MakeRetain<CPDF_Array>();
    while (RetainPtr<CPDF_Object> pObj =
               GetObjectBodyInternal(pObjList, ParseType::kLoose)) {
      // `pObj` cannot be a stream, per ISO 32000-1:2008 section 7.3.8.1.
      if (!pObj->IsStream()) {
        pArray->Append(std::move(pObj));
      }
    }
    return (parse_type == ParseType::kLoose || m_WordBuffer[0] == ']')
               ? std::move(pArray)
               : nullptr;
  }
  if (word[0] == '/') {
    auto word_span = pdfium::make_span(m_WordBuffer).first(m_WordSize);
    return pdfium::MakeRetain<CPDF_Name>(
        m_pPool, PDF_NameDecode(ByteStringView(word_span).Substr(1)));
  }
  if (word == "<<") {
    RetainPtr<CPDF_Dictionary> pDict =
        pdfium::MakeRetain<CPDF_Dictionary>(m_pPool);
    while (true) {
      WordResult inner_word_result = GetNextWord();
      const ByteString& inner_word = inner_word_result.word;
      if (inner_word.IsEmpty())
        return nullptr;

      FX_FILESIZE SavedPos = m_Pos - inner_word.GetLength();
      if (inner_word == ">>")
        break;

      if (inner_word == "endobj") {
        m_Pos = SavedPos;
        break;
      }
      if (inner_word[0] != '/')
        continue;

      ByteString key = PDF_NameDecode(inner_word.AsStringView());
      if (key.IsEmpty() && parse_type == ParseType::kLoose)
        continue;

      RetainPtr<CPDF_Object> pObj =
          GetObjectBodyInternal(pObjList, ParseType::kLoose);
      if (!pObj) {
        if (parse_type == ParseType::kLoose)
          continue;

        ToNextLine();
        return nullptr;
      }

      // `key` has to be "/X" at the minimum.
      // `pObj` cannot be a stream, per ISO 32000-1:2008 section 7.3.8.1.
      if (key.GetLength() > 1 && !pObj->IsStream()) {
        pDict->SetFor(key.Substr(1), std::move(pObj));
      }
    }

    AutoRestorer<FX_FILESIZE> pos_restorer(&m_Pos);
    if (GetNextWord().word != "stream")
      return pDict;
    pos_restorer.AbandonRestoration();
    return ReadStream(std::move(pDict));
  }
  if (word == ">>")
    m_Pos = SavedObjPos;

  return nullptr;
}

RetainPtr<CPDF_Object> CPDF_SyntaxParser::GetIndirectObject(
    CPDF_IndirectObjectHolder* pObjList,
    ParseType parse_type) {
  CPDF_ReadValidator::ScopedSession read_session(GetValidator());
  const FX_FILESIZE saved_pos = GetPos();

  WordResult objnum_word_result = GetNextWord();
  if (!objnum_word_result.is_number || objnum_word_result.word.IsEmpty()) {
    SetPos(saved_pos);
    return nullptr;
  }
  const uint32_t parser_objnum = FXSYS_atoui(objnum_word_result.word.c_str());

  WordResult gennum_word_result = GetNextWord();
  const ByteString& gennum_word = gennum_word_result.word;
  if (!gennum_word_result.is_number || gennum_word.IsEmpty()) {
    SetPos(saved_pos);
    return nullptr;
  }
  const uint32_t parser_gennum = FXSYS_atoui(gennum_word.c_str());

  if (GetKeyword() != "obj") {
    SetPos(saved_pos);
    return nullptr;
  }

  RetainPtr<CPDF_Object> pObj = GetObjectBodyInternal(pObjList, parse_type);
  if (pObj) {
    pObj->SetObjNum(parser_objnum);
    pObj->SetGenNum(parser_gennum);
  }

  return GetValidator()->has_read_problems() ? nullptr : pObj;
}

unsigned int CPDF_SyntaxParser::ReadEOLMarkers(FX_FILESIZE pos) {
  unsigned char byte1 = 0;
  unsigned char byte2 = 0;

  GetCharAt(pos, byte1);
  GetCharAt(pos + 1, byte2);

  if (byte1 == '\r' && byte2 == '\n')
    return 2;

  if (byte1 == '\r' || byte1 == '\n')
    return 1;

  return 0;
}

FX_FILESIZE CPDF_SyntaxParser::FindWordPos(ByteStringView word) {
  AutoRestorer<FX_FILESIZE> pos_restorer(&m_Pos);
  FX_FILESIZE end_offset = FindTag(word);
  while (end_offset >= 0) {
    // Stop searching when word is found.
    if (IsWholeWord(GetPos() - word.GetLength(), m_FileLen, word, true))
      return GetPos() - word.GetLength();

    end_offset = FindTag(word);
  }
  return -1;
}

FX_FILESIZE CPDF_SyntaxParser::FindStreamEndPos() {
  const ByteStringView kEndStreamStr("endstream");
  const ByteStringView kEndObjStr("endobj");

  FX_FILESIZE endStreamWordOffset = FindWordPos(kEndStreamStr);
  FX_FILESIZE endObjWordOffset = FindWordPos(kEndObjStr);

  // Can't find "endstream" or "endobj".
  if (endStreamWordOffset < 0 && endObjWordOffset < 0) {
    return -1;
  }

  if (endStreamWordOffset < 0 && endObjWordOffset >= 0) {
    // Correct the position of end stream.
    endStreamWordOffset = endObjWordOffset;
  } else if (endStreamWordOffset >= 0 && endObjWordOffset < 0) {
    // Correct the position of end obj.
    endObjWordOffset = endStreamWordOffset;
  } else if (endStreamWordOffset > endObjWordOffset) {
    endStreamWordOffset = endObjWordOffset;
  }

  int numMarkers = ReadEOLMarkers(endStreamWordOffset - 2);
  if (numMarkers == 2) {
    endStreamWordOffset -= 2;
  } else {
    numMarkers = ReadEOLMarkers(endStreamWordOffset - 1);
    if (numMarkers == 1) {
      endStreamWordOffset -= 1;
    }
  }
  if (endStreamWordOffset < GetPos()) {
    return -1;
  }
  return endStreamWordOffset;
}

RetainPtr<CPDF_Stream> CPDF_SyntaxParser::ReadStream(
    RetainPtr<CPDF_Dictionary> pDict) {
  RetainPtr<const CPDF_Number> pLenObj =
      ToNumber(pDict->GetDirectObjectFor("Length"));
  FX_FILESIZE len = pLenObj ? pLenObj->GetInteger() : -1;

  // Locate the start of stream.
  ToNextLine();
  const FX_FILESIZE streamStartPos = GetPos();

  if (len > 0) {
    FX_SAFE_FILESIZE pos = GetPos();
    pos += len;
    if (!pos.IsValid() || pos.ValueOrDie() >= m_FileLen)
      len = -1;
  }

  RetainPtr<IFX_SeekableReadStream> substream;
  if (len > 0) {
    // Check data availability first to allow the Validator to request data
    // smoothly, without jumps.
    if (!GetValidator()->CheckDataRangeAndRequestIfUnavailable(
            m_HeaderOffset + GetPos(), len)) {
      return nullptr;
    }

    substream = pdfium::MakeRetain<ReadableSubStream>(
        GetValidator(), m_HeaderOffset + GetPos(), len);
    SetPos(GetPos() + len);
  }

  const ByteStringView kEndStreamStr("endstream");
  const ByteStringView kEndObjStr("endobj");

  // Note, we allow zero length streams as we need to pass them through when we
  // are importing pages into a new document.
  if (len >= 0) {
    CPDF_ReadValidator::ScopedSession read_session(GetValidator());
    m_Pos += ReadEOLMarkers(GetPos());
    UNSAFE_TODO(
        FXSYS_memset(m_WordBuffer.data(), 0, kEndStreamStr.GetLength() + 1));
    GetNextWordInternal();
    if (GetValidator()->has_read_problems())
      return nullptr;

    // Earlier version of PDF specification doesn't require EOL marker before
    // 'endstream' keyword. If keyword 'endstream' follows the bytes in
    // specified length, it signals the end of stream.
    if (memcmp(m_WordBuffer.data(), kEndStreamStr.unterminated_unsigned_str(),
               kEndStreamStr.GetLength()) != 0) {
      substream.Reset();
      len = -1;
      SetPos(streamStartPos);
    }
  }

  if (len < 0) {
    // If len is not available or incorrect, len needs to be calculated
    // by searching the keywords "endstream" or "endobj".
    const FX_FILESIZE streamEndPos = FindStreamEndPos();
    if (streamEndPos < 0)
      return nullptr;

    len = streamEndPos - streamStartPos;
    DCHECK_GE(len, 0);
    if (len > 0) {
      SetPos(streamStartPos);
      // Check data availability first to allow the Validator to request data
      // smoothly, without jumps.
      if (!GetValidator()->CheckDataRangeAndRequestIfUnavailable(
              m_HeaderOffset + GetPos(), len)) {
        return nullptr;
      }

      substream = pdfium::MakeRetain<ReadableSubStream>(
          GetValidator(), m_HeaderOffset + GetPos(), len);
      SetPos(GetPos() + len);
    }
  }

  RetainPtr<CPDF_Stream> stream;
  if (substream) {
    // It is unclear from CPDF_SyntaxParser's perspective what object
    // `substream` is ultimately holding references to. To avoid unexpectedly
    // changing object lifetimes by handing `substream` to `stream`, make a
    // copy of the data here.
    auto data = FixedSizeDataVector<uint8_t>::Uninit(substream->GetSize());
    bool did_read = substream->ReadBlockAtOffset(data.span(), 0);
    CHECK(did_read);
    auto data_as_stream =
        pdfium::MakeRetain<CFX_ReadOnlyVectorStream>(std::move(data));

    stream = pdfium::MakeRetain<CPDF_Stream>(std::move(data_as_stream),
                                             std::move(pDict));
  } else {
    DCHECK(!len);
    stream = pdfium::MakeRetain<CPDF_Stream>(std::move(pDict));
  }
  const FX_FILESIZE end_stream_offset = GetPos();
  UNSAFE_TODO(FXSYS_memset(m_WordBuffer.data(), 0, kEndObjStr.GetLength() + 1));
  GetNextWordInternal();

  // Allow whitespace after endstream and before a newline.
  unsigned char ch = 0;
  while (GetNextChar(ch)) {
    if (!PDFCharIsWhitespace(ch) || PDFCharIsLineEnding(ch))
      break;
  }
  SetPos(GetPos() - 1);

  int numMarkers = ReadEOLMarkers(GetPos());
  if (m_WordSize == static_cast<unsigned int>(kEndObjStr.GetLength()) &&
      numMarkers != 0 &&
      memcmp(m_WordBuffer.data(), kEndObjStr.unterminated_unsigned_str(),
             kEndObjStr.GetLength()) == 0) {
    SetPos(end_stream_offset);
  }
  return stream;
}

uint32_t CPDF_SyntaxParser::GetDirectNum() {
  if (GetNextWordInternal() != WordType::kNumber)
    return 0;

  m_WordBuffer[m_WordSize] = 0;
  return FXSYS_atoui(pdfium::as_chars(pdfium::make_span(m_WordBuffer)).data());
}

RetainPtr<CPDF_ReadValidator> CPDF_SyntaxParser::GetValidator() const {
  return m_pFileAccess;
}

bool CPDF_SyntaxParser::IsWholeWord(FX_FILESIZE startpos,
                                    FX_FILESIZE limit,
                                    ByteStringView tag,
                                    bool checkKeyword) {
  const uint32_t taglen = tag.GetLength();

  bool bCheckLeft = !PDFCharIsDelimiter(tag[0]) && !PDFCharIsWhitespace(tag[0]);
  bool bCheckRight = !PDFCharIsDelimiter(tag[taglen - 1]) &&
                     !PDFCharIsWhitespace(tag[taglen - 1]);

  uint8_t ch;
  if (bCheckRight && startpos + static_cast<int32_t>(taglen) <= limit &&
      GetCharAt(startpos + static_cast<int32_t>(taglen), ch)) {
    if (PDFCharIsNumeric(ch) || PDFCharIsOther(ch) ||
        (checkKeyword && PDFCharIsDelimiter(ch))) {
      return false;
    }
  }

  if (bCheckLeft && startpos > 0 && GetCharAt(startpos - 1, ch)) {
    if (PDFCharIsNumeric(ch) || PDFCharIsOther(ch) ||
        (checkKeyword && PDFCharIsDelimiter(ch))) {
      return false;
    }
  }
  return true;
}

bool CPDF_SyntaxParser::BackwardsSearchToWord(ByteStringView word,
                                              FX_FILESIZE limit) {
  int32_t taglen = word.GetLength();
  if (taglen == 0)
    return false;

  FX_FILESIZE pos = m_Pos;
  int32_t offset = taglen - 1;
  while (true) {
    if (limit && pos <= m_Pos - limit)
      return false;

    uint8_t byte;
    if (!GetCharAtBackward(pos, &byte))
      return false;

    if (byte == word[offset]) {
      offset--;
      if (offset >= 0) {
        pos--;
        continue;
      }
      if (IsWholeWord(pos, limit, word, false)) {
        m_Pos = pos;
        return true;
      }
    }
    offset = byte == word[taglen - 1] ? taglen - 2 : taglen - 1;
    pos--;
    if (pos < 0)
      return false;
  }
}

FX_FILESIZE CPDF_SyntaxParser::FindTag(ByteStringView tag) {
  const FX_FILESIZE startpos = GetPos();
  const int32_t taglen = tag.GetLength();
  DCHECK_GT(taglen, 0);

  int32_t match = 0;
  while (true) {
    uint8_t ch;
    if (!GetNextChar(ch))
      return -1;

    if (ch == tag[match]) {
      match++;
      if (match == taglen)
        return GetPos() - startpos - taglen;
    } else {
      match = ch == tag[0] ? 1 : 0;
    }
  }
}

bool CPDF_SyntaxParser::IsPositionRead(FX_FILESIZE pos) const {
  return m_BufOffset <= pos &&
         pos < static_cast<FX_FILESIZE>(m_BufOffset + m_pFileBuf.size());
}
