// Copyright 2016 PDFium Authors. All rights reserved.
// 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_linearized_header.h"

#include <algorithm>
#include <utility>

#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_number.h"
#include "core/fpdfapi/parser/cpdf_syntax_parser.h"
#include "third_party/base/ptr_util.h"

namespace {

constexpr FX_FILESIZE kLinearizedHeaderOffset = 9;

template <class T>
bool IsValidNumericDictionaryValue(const CPDF_Dictionary* pDict,
                                   const char* key,
                                   T min_value,
                                   bool must_exist = true) {
  if (!pDict->KeyExist(key))
    return !must_exist;
  const CPDF_Number* pNum = ToNumber(pDict->GetObjectFor(key));
  if (!pNum || !pNum->IsInteger())
    return false;
  const int raw_value = pNum->GetInteger();
  if (!pdfium::base::IsValueInRangeForNumericType<T>(raw_value))
    return false;
  return static_cast<T>(raw_value) >= min_value;
}

bool IsLinearizedHeaderValid(const CPDF_LinearizedHeader* header,
                             FX_FILESIZE file_size) {
  ASSERT(header);
  return header->GetFileSize() == file_size &&
         header->GetMainXRefTableFirstEntryOffset() < file_size &&
         header->GetPageCount() > 0 &&
         header->GetFirstPageEndOffset() < file_size &&
         header->GetLastXRefOffset() < file_size &&
         header->GetHintStart() < file_size;
}

}  // namespace

// static
std::unique_ptr<CPDF_LinearizedHeader> CPDF_LinearizedHeader::Parse(
    CPDF_SyntaxParser* parser) {
  parser->SetPos(kLinearizedHeaderOffset);

  const auto pDict = ToDictionary(
      parser->GetIndirectObject(nullptr, CPDF_SyntaxParser::ParseType::kLoose));

  if (!pDict || !pDict->KeyExist("Linearized") ||
      !IsValidNumericDictionaryValue<FX_FILESIZE>(pDict.get(), "L", 1) ||
      !IsValidNumericDictionaryValue<uint32_t>(pDict.get(), "P", 0, false) ||
      !IsValidNumericDictionaryValue<FX_FILESIZE>(pDict.get(), "T", 1) ||
      !IsValidNumericDictionaryValue<uint32_t>(pDict.get(), "N", 0) ||
      !IsValidNumericDictionaryValue<FX_FILESIZE>(pDict.get(), "E", 1) ||
      !IsValidNumericDictionaryValue<uint32_t>(pDict.get(), "O", 1)) {
    return nullptr;
  }
  // Move parser to the start of the xref table for the documents first page.
  // (skpping endobj keyword)
  if (parser->GetNextWord(nullptr) != "endobj")
    return nullptr;

  auto result = pdfium::WrapUnique(
      new CPDF_LinearizedHeader(pDict.get(), parser->GetPos()));

  if (!IsLinearizedHeaderValid(result.get(),
                               parser->GetFileAccess()->GetSize())) {
    return nullptr;
  }
  return result;
}

CPDF_LinearizedHeader::CPDF_LinearizedHeader(const CPDF_Dictionary* pDict,
                                             FX_FILESIZE szLastXRefOffset)
    : m_szFileSize(pDict->GetIntegerFor("L")),
      m_dwFirstPageNo(pDict->GetIntegerFor("P")),
      m_szMainXRefTableFirstEntryOffset(pDict->GetIntegerFor("T")),
      m_PageCount(pDict->GetIntegerFor("N")),
      m_szFirstPageEndOffset(pDict->GetIntegerFor("E")),
      m_FirstPageObjNum(pDict->GetIntegerFor("O")),
      m_szLastXRefOffset(szLastXRefOffset) {
  const CPDF_Array* pHintStreamRange = pDict->GetArrayFor("H");
  const size_t nHintStreamSize =
      pHintStreamRange ? pHintStreamRange->GetCount() : 0;
  if (nHintStreamSize == 2 || nHintStreamSize == 4) {
    m_szHintStart = std::max(pHintStreamRange->GetIntegerAt(0), 0);
    const FX_SAFE_UINT32 safe_hint_length = pHintStreamRange->GetIntegerAt(1);
    if (safe_hint_length.IsValid())
      m_HintLength = safe_hint_length.ValueOrDie();
  }
}

CPDF_LinearizedHeader::~CPDF_LinearizedHeader() {}

bool CPDF_LinearizedHeader::HasHintTable() const {
  return GetPageCount() > 1 && GetHintStart() > 0 && GetHintLength() > 0;
}
