// 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.

#include <cstdint>

#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_boolean.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_hint_tables.h"
#include "core/fpdfapi/parser/cpdf_linearized_header.h"
#include "core/fpdfapi/parser/cpdf_number.h"
#include "core/fxcrt/cfx_bitstream.h"
#include "core/fxcrt/span.h"

int32_t GetData(const int32_t** data32, const uint8_t** data, size_t* size) {
  const int32_t* ret = *data32;
  ++(*data32);
  *data += 4;
  *size -= 4;
  return *ret;
}

class HintTableForFuzzing final : public CPDF_HintTables {
 public:
  HintTableForFuzzing(CPDF_LinearizedHeader* pLinearized,
                      int shared_hint_table_offset)
      : CPDF_HintTables(nullptr, pLinearized),
        shared_hint_table_offset_(shared_hint_table_offset) {}
  ~HintTableForFuzzing() override = default;

  void Fuzz(const uint8_t* data, size_t size) {
    if (shared_hint_table_offset_ <= 0)
      return;

    if (size < static_cast<size_t>(shared_hint_table_offset_))
      return;

    CFX_BitStream bs(pdfium::make_span(data, size));
    if (!ReadPageHintTable(&bs))
      return;
    ReadSharedObjHintTable(&bs, shared_hint_table_offset_);
  }

 private:
  int shared_hint_table_offset_;
};

class FakeLinearized final : public CPDF_LinearizedHeader {
 public:
  explicit FakeLinearized(CPDF_Dictionary* linearized_dict)
      : CPDF_LinearizedHeader(linearized_dict, 0) {}
};

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  // Need 28 bytes for |linearized_dict|.
  // The header section of page offset hint table is 36 bytes.
  // The header section of shared object hint table is 24 bytes.
  if (size < 28 + 36 + 24)
    return 0;

  const int32_t* data32 = reinterpret_cast<const int32_t*>(data);

  auto linearized_dict = pdfium::MakeRetain<CPDF_Dictionary>();
  // Set initial value.
  linearized_dict->SetNewFor<CPDF_Boolean>("Linearized", true);
  // Set first page end offset
  linearized_dict->SetNewFor<CPDF_Number>("E", GetData(&data32, &data, &size));
  // Set page count
  linearized_dict->SetNewFor<CPDF_Number>("N", GetData(&data32, &data, &size));
  // Set first page obj num
  linearized_dict->SetNewFor<CPDF_Number>("O", GetData(&data32, &data, &size));
  // Set first page no
  linearized_dict->SetNewFor<CPDF_Number>("P", GetData(&data32, &data, &size));

  auto hint_info = pdfium::MakeRetain<CPDF_Array>();
  // Add primary hint stream offset
  hint_info->AppendNew<CPDF_Number>(GetData(&data32, &data, &size));
  // Add primary hint stream size
  hint_info->AppendNew<CPDF_Number>(GetData(&data32, &data, &size));
  // Set hint stream info.
  linearized_dict->SetFor("H", std::move(hint_info));

  const int shared_hint_table_offset = GetData(&data32, &data, &size);

  {
    FakeLinearized linearized(linearized_dict.Get());
    HintTableForFuzzing hint_table(&linearized, shared_hint_table_offset);
    hint_table.Fuzz(data, size);
  }
  return 0;
}
