// 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 "third_party/base/containers/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;
}
