// Copyright 2021 The 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.

#include <fuzzer/FuzzedDataProvider.h>

#include <string>

#include "public/fpdf_formfill.h"
#include "testing/fuzzers/pdf_fuzzer_templates.h"
#include "testing/fuzzers/pdfium_fuzzer_helper.h"

class PDFiumXDPFuzzer : public PDFiumFuzzerHelper {
 public:
  PDFiumXDPFuzzer() = default;
  ~PDFiumXDPFuzzer() override = default;

  int GetFormCallbackVersion() const override { return 2; }

  bool OnFormFillEnvLoaded(FPDF_DOCUMENT doc) override {
    int form_type = FPDF_GetFormType(doc);
    if (form_type != FORMTYPE_XFA_FULL && form_type != FORMTYPE_XFA_FOREGROUND)
      return false;
    return FPDF_LoadXFA(doc);
  }
};

struct Tag {
  const char* tag_name;
  const char* tag_start;
  const char* tag_end;
};

const Tag kTagData[]{
    {.tag_name = "config",
     .tag_start =
         R""(<xfa:config xmlns:xfa="http://www.xfa.org/schema/xci/3.1/">)"",
     .tag_end = "</xfa:config>"},
    {.tag_name = "template",
     .tag_start =
         R""(<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">)"",
     .tag_end = "</template>"},
    {.tag_name = "sourceSet",
     .tag_start =
         R""(<sourceSet xmlns="http://www.xfa.org/schema/xfa-source-set/2.7/">)"",
     .tag_end = "</sourceSet>"},
    {.tag_name = "localeSet",
     .tag_start =
         R""(<localeSet xmlns="http://www.xfa.org/schema/xfa-locale-set/2.7/">)"",
     .tag_end = "</localeSet>"},
    {.tag_name = "dataSet",
     .tag_start =
         R""(<xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">)"",
     .tag_end = "</xfa:datasets>"},
    {.tag_name = "connectionSet",
     .tag_start =
         R""(<connectionSet xmlns="http://www.xfa.org/schema/xfa-connection-set/2.8/">)"",
     .tag_end = "</connectionSet>"},
    {.tag_name = "xdc",
     .tag_start =
         R""(<xsl:xdc xmlns:xdc="http://www.xfa.org/schema/xdc/1.0/">)"",
     .tag_end = "</xsl:xdc>"},
    {.tag_name = "signature",
     .tag_start = R""(<signature xmlns="http://www.w3.org/2000/09/xmldsig#">)"",
     .tag_end = "</signature>"},
    {.tag_name = "stylesheet",
     .tag_start =
         R""(<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" id="identifier">)"",
     .tag_end = "</stylesheet>"},
    {.tag_name = "xfdf",
     .tag_start =
         R""(<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">)"",
     .tag_end = "</xfdf>"},
    {.tag_name = "xmpmeta",
     .tag_start =
         R""(<xmpmeta xmlns="http://ns.adobe.com/xmpmeta/" xml:space="preserve">)"",
     .tag_end = "</xmpmeta>"}};

std::string CreateObject(int obj_num, const std::string& body) {
  std::string obj_template = R""($1 0 obj
$2
endobj
)"";

  obj_template.replace(obj_template.find("$1"), 2, std::to_string(obj_num));
  obj_template.replace(obj_template.find("$2"), 2, body);
  return obj_template;
}

std::string CreateStreamObject(int obj_num, const std::string& body) {
  std::string obj_template = R""($1 0 obj
<</Length $2>>
stream
$3
endstream
endobj
)"";

  obj_template.replace(obj_template.find("$1"), 2, std::to_string(obj_num));
  obj_template.replace(obj_template.find("$2"), 2,
                       std::to_string(body.size() + 1));
  obj_template.replace(obj_template.find("$3"), 2, body);

  return obj_template;
}

std::string GenXrefEntry(size_t offset) {
  return std::string(10 - std::to_string(offset).size(), '0') +
         std::to_string(offset) + " 00000 n\n";
}

std::string GenTagBody(const Tag& tag, FuzzedDataProvider* data_provider) {
  std::string tag_content = data_provider->ConsumeRandomLengthString();
  return tag.tag_start + tag_content + tag.tag_end;
}

std::string GenXDPPdfFile(FuzzedDataProvider* data_provider) {
  std::vector<std::string> pdf_objects;
  std::string pdf_header =
      std::string(reinterpret_cast<const char*>(kSimplePdfHeader),
                  sizeof(kSimplePdfHeader));

  pdf_objects.push_back(CreateObject(1, kCatalog));

  std::string xfa_obj = kSimpleXfaObjWrapper;
  Tag tag1 = data_provider->PickValueInArray(kTagData);
  Tag tag2 = data_provider->PickValueInArray(kTagData);
  Tag tag3 = data_provider->PickValueInArray(kTagData);
  xfa_obj.replace(xfa_obj.find("$1"), 2, tag1.tag_name);
  xfa_obj.replace(xfa_obj.find("$2"), 2, tag2.tag_name);
  xfa_obj.replace(xfa_obj.find("$3"), 2, tag3.tag_name);
  pdf_objects.push_back(CreateObject(2, xfa_obj));
  pdf_objects.push_back(CreateObject(3, kSimplePagesObj));
  pdf_objects.push_back(CreateObject(4, kSimplePageObj));

  // preamble
  pdf_objects.push_back(CreateStreamObject(5, kSimplePreamble));

  // The three XFA tags
  pdf_objects.push_back(CreateStreamObject(6, GenTagBody(tag1, data_provider)));
  pdf_objects.push_back(CreateStreamObject(7, GenTagBody(tag2, data_provider)));
  pdf_objects.push_back(CreateStreamObject(8, GenTagBody(tag3, data_provider)));

  // postamble
  pdf_objects.push_back(CreateStreamObject(9, kSimplePostamble));

  // Create the xref table
  std::string xref = R""(xref
0 10
0000000000 65535 f
)"";

  // Add xref entries
  size_t curr_offset = pdf_header.size();
  for (const auto& ostr : pdf_objects) {
    xref += GenXrefEntry(curr_offset);
    curr_offset += ostr.size();
  }

  std::string footer = R""(trailer
<</Root 1 0 R /Size 10>>
startxref
$1
%%EOF)"";
  footer.replace(footer.find("$1"), 2, std::to_string(curr_offset));

  std::string pdf_core;
  for (const auto& ostr : pdf_objects) {
    pdf_core += ostr;
  }

  // Return the full PDF
  return pdf_header + pdf_core + xref + footer;
}

bool IsValidForFuzzing(const uint8_t* data, size_t size) {
  if (size > 2048) {
    return false;
  }
  const char* ptr = reinterpret_cast<const char*>(data);
  for (size_t i = 0; i < size; i++) {
    if (!std::isspace(ptr[i]) && !std::isprint(ptr[i])) {
      return false;
    }
  }
  return true;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  if (!IsValidForFuzzing(data, size)) {
    return 0;
  }

  FuzzedDataProvider data_provider(data, size);
  std::string xfa_final_str = GenXDPPdfFile(&data_provider);

#ifdef PDFIUM_FUZZER_DUMP
  for (size_t i = 0; i < xfa_final_str.size(); i++) {
    putc(xfa_final_str[i], stdout);
  }
#endif

  PDFiumXDPFuzzer fuzzer;
  fuzzer.RenderPdf(xfa_final_str.c_str(), xfa_final_str.size());
  return 0;
}
