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

import("../../pdfium.gni")

config("fuzzer_config") {
  configs = [
    "../..:pdfium_strict_config",
    "../..:pdfium_noshorten_config",
  ]
  defines = []
  include_dirs = [ "../.." ]
}

# All possible "pdfium_fuzzer"s.
fuzzer_list = [
  "pdf_cmap_fuzzer",
  "pdf_codec_a85_fuzzer",
  "pdf_codec_fax_fuzzer",
  "pdf_codec_icc_fuzzer",
  "pdf_codec_jbig2_fuzzer",
  "pdf_codec_rle_fuzzer",
  "pdf_font_fuzzer",
  "pdf_hint_table_fuzzer",
  "pdf_jpx_fuzzer",
  "pdf_psengine_fuzzer",
  "pdf_scanlinecompositor_fuzzer",
  "pdf_streamparser_fuzzer",
  "pdf_xml_fuzzer",
  "pdfium_fuzzer",
]
if (pdf_enable_v8) {
  fuzzer_list += [
    "pdf_cjs_util_fuzzer",
    "pdf_fx_date_helpers_fuzzer",
  ]
  if (pdf_enable_xfa) {
    fuzzer_list += [
      "pdf_bidi_fuzzer",
      "pdf_cfgas_stringformatter_fuzzer",
      "pdf_cfx_barcode_fuzzer",
      "pdf_codec_jpeg_fuzzer",
      "pdf_css_fuzzer",
      "pdf_codec_bmp_fuzzer",
      "pdf_codec_gif_fuzzer",
      "pdf_codec_png_fuzzer",
      "pdf_codec_tiff_fuzzer",
      "pdf_formcalc_context_fuzzer",
      "pdf_formcalc_fuzzer",
      "pdf_formcalc_translate_fuzzer",
      "pdf_lzw_fuzzer",
      "pdfium_xfa_fuzzer",
      "pdfium_xfa_lpm_fuzzer",
    ]
  }
}
if (is_clang) {
  # Fuzzers that use FuzzedDataProvider can only be built with Clang.
  fuzzer_list += [
    "pdf_cpdf_tounicodemap_fuzzer",
    "pdf_nametree_fuzzer",
  ]
  if (pdf_enable_xfa) {
    fuzzer_list += [
      "pdf_xfa_fdp_fuzzer",
      "pdf_xfa_raw_fuzzer",
      "pdf_xfa_xdp_fdp_fuzzer",
    ]
  }
}

# Note that this only compiles all the fuzzers, to prevent compile breakages.
# It does not link and create fuzzer executables. That is done in Chromium.
group("fuzzers") {
  testonly = true
  deps = []
  foreach(fuzzer, fuzzer_list) {
    deps += [ ":${fuzzer}_src" ]
  }

  if (is_component_build) {
    deps += [ ":fuzzer_impls" ]
  }
}

source_set("fuzzer_pdf_templates") {
  sources = [ "pdf_fuzzer_templates.h" ]
}

source_set("fuzzer_init") {
  testonly = true
  sources = [ "pdf_fuzzer_init.cc" ]
  include_dirs = [ "../.." ]
  deps = [
    "../../:pdfium_public_headers",
    "../../fpdfsdk",
  ]
}

if (pdf_enable_xfa) {
  assert(pdf_enable_v8)
  source_set("fuzzer_xfa_process_state") {
    testonly = !is_component_build
    sources = [
      "xfa_process_state.cc",
      "xfa_process_state.h",
    ]
    configs += [ ":fuzzer_config" ]
    deps = [
      "../../fxjs:gc",
      "//v8",
    ]
  }
}

source_set("fuzzer_init_public") {
  testonly = true
  sources = [ "pdf_fuzzer_init_public.cc" ]
  include_dirs = [ "../.." ]
  configs += [ "../../:pdfium_core_config" ]
  deps = [
    ":fuzzer_utils",
    "../../:pdfium_public_headers",
    "../../core/fxcrt",
    "../../fpdfsdk",
  ]
  if (pdf_enable_v8) {
    configs += [ "//v8:external_startup_data" ]
    deps += [
      "../:test_support",
      "../../fxjs",
      "//v8",
      "//v8:v8_libplatform",
    ]
    if (pdf_enable_xfa) {
      deps += [ ":fuzzer_xfa_process_state" ]
    }
  }

  # TODO(crbug.com/40031409): Fix code that adds exit-time destructors and
  # enable the diagnostic by removing this line.
  configs += [ "//build/config/compiler:no_exit_time_destructors" ]
}

if (is_component_build) {
  group("fuzzer_impls") {
    testonly = true
    deps = []
    foreach(fuzzer, fuzzer_list) {
      deps += [ ":${fuzzer}_impl" ]
    }
    if (pdf_enable_xfa) {
      deps += [ ":fuzzer_xfa_process_state" ]
    }
  }
}

source_set("fuzzer_helper") {
  testonly = !is_component_build
  sources = [
    "pdfium_fuzzer_helper.cc",
    "pdfium_fuzzer_helper.h",
  ]
  configs += [ ":fuzzer_config" ]
  deps = [
    "../../:pdfium_public_headers",
    "../../core/fxcrt",
    "../../fpdfsdk",
  ]
}

source_set("fuzzer_utils") {
  # In component builds, the pdfium target (which is not testonly) depends on
  # the fuzzer sources, which may depend on this target, so add testonly only in
  # non-component builds.
  testonly = !is_component_build
  sources = [
    "pdfium_fuzzer_util.cc",
    "pdfium_fuzzer_util.h",
  ]
  deps = [ "../../:pdfium_public_headers" ]
  include_dirs = [ "../.." ]
}

template("pdfium_fuzzer") {
  is_public = defined(invoker.public_fuzzer) && invoker.public_fuzzer
  if (is_public) {
    init_dep = ":fuzzer_init_public"
  } else {
    init_dep = ":fuzzer_init"
  }
  if (is_component_build) {
    # In component builds, fuzzers are split into "_impl" and "_src" targets.
    # The "_impl" target exports the fuzzer implementation. The "_src" target
    # is a thin wrapper that imports the fuzzer from PDFium; this gets linked
    # into the real fuzzer executable. The real fuzzer target has to depend on
    # both the "_impl" and "_src" targets.
    # In static builds, there's only a single "_src" target that contains the
    # implementation and statically links in PDFium.

    impl_name = target_name + "_impl"
    template_target_name = target_name
    source_set("${target_name}_src") {
      testonly = true
      sources = [ "component_fuzzer_template.cc" ]
      deps = [
        "../../:pdfium_public_headers",
        init_dep,
      ]
      configs += [ ":fuzzer_config" ]
      defines = [ "FUZZER_IMPL=${template_target_name}" ]
    }
  } else {
    impl_name = target_name + "_src"
  }
  source_set(impl_name) {
    testonly = true
    sources = invoker.sources
    defines = []
    deps = []
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }
    configs += [ ":fuzzer_config" ]
    if (is_component_build) {
      # |export| should be consistent with FPDF_EXPORT In public/fpdfview.h.
      if (is_win) {
        export = "__declspec(dllexport)"
      } else {
        export = "__attribute__((visibility(\"default\")))"
      }
      defines += [ "LLVMFuzzerTestOneInput=${export} ${template_target_name}" ]
      deps += [ "../../:pdfium_public_headers" ]
    } else {
      testonly = true
      deps += [
        "../../:pdfium",
        init_dep,
      ]
    }
    if (is_public && pdf_enable_xfa) {
      deps += [ ":fuzzer_xfa_process_state" ]
    }
  }
}

if (pdf_enable_v8) {
  pdfium_fuzzer("pdf_cjs_util_fuzzer") {
    sources = [ "pdf_cjs_util_fuzzer.cc" ]
    deps = [
      "../../core/fxcrt",
      "../../fpdfsdk",
      "../../fxjs",
    ]
  }
  pdfium_fuzzer("pdf_fx_date_helpers_fuzzer") {
    sources = [ "pdf_fx_date_helpers_fuzzer.cc" ]
    deps = [
      "../../core/fxcrt",
      "../../fpdfsdk",
      "../../fxjs",
    ]
  }

  if (pdf_enable_xfa) {
    pdfium_fuzzer("pdf_bidi_fuzzer") {
      sources = [ "pdf_bidi_fuzzer.cc" ]
      deps = [
        "../../:freetype_common",
        "../../core/fxcrt",
        "../../core/fxge",
        "../../xfa/fgas/font",
        "../../xfa/fgas/layout",
        "//third_party/icu:icuuc",
      ]
    }

    pdfium_fuzzer("pdf_cfgas_stringformatter_fuzzer") {
      sources = [ "pdf_cfgas_stringformatter_fuzzer.cc" ]
      deps = [
        ":fuzzer_utils",
        "../../core/fxcrt",
        "../../fpdfsdk",
        "../../fxjs:gc",
        "../../xfa/fgas/crt",
        "../../xfa/fxfa",
        "../../xfa/fxfa/parser",
      ]
      public_fuzzer = true
    }

    pdfium_fuzzer("pdf_cfx_barcode_fuzzer") {
      sources = [ "pdf_cfx_barcode_fuzzer.cc" ]
      deps = [
        "../../core/fxcrt",
        "../../fxbarcode",
        "//third_party/icu:icuuc",
      ]
    }

    pdfium_fuzzer("pdf_codec_bmp_fuzzer") {
      sources = [
        "pdf_codec_bmp_fuzzer.cc",
        "xfa_codec_fuzzer.h",
      ]
      deps = [
        "../../core/fxcodec",
        "../../core/fxcrt",
        "../../core/fxge",
      ]
    }

    pdfium_fuzzer("pdf_codec_gif_fuzzer") {
      sources = [
        "pdf_codec_gif_fuzzer.cc",
        "xfa_codec_fuzzer.h",
      ]
      deps = [
        "../../core/fxcodec",
        "../../core/fxcrt",
        "../../core/fxge",
      ]
    }

    pdfium_fuzzer("pdf_lzw_fuzzer") {
      sources = [ "pdf_lzw_fuzzer.cc" ]
      deps = [ "../../core/fxcodec" ]
    }

    pdfium_fuzzer("pdf_codec_jpeg_fuzzer") {
      sources = [
        "pdf_codec_jpeg_fuzzer.cc",
        "xfa_codec_fuzzer.h",
      ]
      deps = [
        "../../core/fxcodec",
        "../../core/fxcrt",
        "../../core/fxge",
      ]
    }

    pdfium_fuzzer("pdf_codec_png_fuzzer") {
      sources = [
        "pdf_codec_png_fuzzer.cc",
        "xfa_codec_fuzzer.h",
      ]
      deps = [
        "../../core/fxcodec",
        "../../core/fxcrt",
        "../../core/fxge",
      ]
    }

    pdfium_fuzzer("pdf_codec_tiff_fuzzer") {
      sources = [
        "pdf_codec_tiff_fuzzer.cc",
        "xfa_codec_fuzzer.h",
      ]
      deps = [
        "../../core/fxcodec",
        "../../core/fxcrt",
        "../../core/fxge",
      ]
    }

    pdfium_fuzzer("pdf_css_fuzzer") {
      sources = [ "pdf_css_fuzzer.cc" ]
      deps = [
        "../../core/fxcrt",
        "../../core/fxcrt/css",
      ]
    }

    pdfium_fuzzer("pdf_formcalc_translate_fuzzer") {
      sources = [ "pdf_formcalc_translate_fuzzer.cc" ]
      deps = [
        ":fuzzer_utils",
        "../../core/fxcrt",
        "../../fpdfsdk",
        "../../fxjs",
      ]
      public_fuzzer = true
    }

    pdfium_fuzzer("pdf_formcalc_context_fuzzer") {
      sources = [ "pdf_formcalc_context_fuzzer.cc" ]
      deps = [
        ":fuzzer_helper",
        "../../:pdfium_public_headers",
        "../../core/fxcrt",
        "../../fpdfsdk",
        "../../fpdfsdk/fpdfxfa",
        "../../fxjs",
        "../../xfa/fxfa",
      ]
      public_fuzzer = true
    }

    pdfium_fuzzer("pdf_formcalc_fuzzer") {
      sources = [ "pdf_formcalc_fuzzer.cc" ]
      deps = [
        ":fuzzer_utils",
        "../../core/fxcrt",
        "../../fxjs:gc",
        "../../xfa/fxfa/formcalc",
      ]
      public_fuzzer = true
    }

    pdfium_fuzzer("pdfium_xfa_fuzzer") {
      sources = [ "pdfium_xfa_fuzzer.cc" ]
      deps = [
        ":fuzzer_helper",
        "../../:pdfium_public_headers",
      ]
      public_fuzzer = true
    }

    pdfium_fuzzer("pdfium_xfa_lpm_fuzzer") {
      sources = [
        "pdfium_xfa_lpm_fuzz_stub.cc",
        "pdfium_xfa_lpm_fuzz_stub.h",
      ]
      deps = [
        ":fuzzer_helper",
        "../../:pdfium_public_headers",
      ]
      public_fuzzer = true
    }
  }
}

if (is_clang) {
  pdfium_fuzzer("pdf_cpdf_tounicodemap_fuzzer") {
    sources = [ "pdf_cpdf_tounicodemap_fuzzer.cc" ]
    deps = [
      "../../core/fpdfapi/font",
      "../../core/fpdfapi/parser",
      "../../core/fxcrt",
    ]
  }

  pdfium_fuzzer("pdf_nametree_fuzzer") {
    sources = [ "pdf_nametree_fuzzer.cc" ]
    deps = [
      "../../core/fpdfapi/page",
      "../../core/fpdfapi/parser",
      "../../core/fpdfdoc",
    ]
  }
  if (pdf_enable_xfa) {
    pdfium_fuzzer("pdf_xfa_fdp_fuzzer") {
      sources = [ "pdf_xfa_fdp_fuzzer.cc" ]
      deps = [
        ":fuzzer_helper",
        ":fuzzer_pdf_templates",
        "../../core/fxcrt",
      ]
      public_fuzzer = true
    }
    pdfium_fuzzer("pdf_xfa_raw_fuzzer") {
      sources = [ "pdf_xfa_raw_fuzzer.cc" ]
      deps = [
        ":fuzzer_helper",
        ":fuzzer_pdf_templates",
      ]
      public_fuzzer = true
    }
    pdfium_fuzzer("pdf_xfa_xdp_fdp_fuzzer") {
      sources = [ "pdf_xfa_xdp_fdp_fuzzer.cc" ]
      deps = [
        ":fuzzer_helper",
        ":fuzzer_pdf_templates",
      ]
      public_fuzzer = true
    }
  }
}

pdfium_fuzzer("pdf_cmap_fuzzer") {
  sources = [ "pdf_cmap_fuzzer.cc" ]
  deps = [
    "../../:freetype_common",
    "../../core/fpdfapi/font",
    "../../core/fxcrt",
    "../../core/fxge",
  ]
}

pdfium_fuzzer("pdf_codec_a85_fuzzer") {
  sources = [ "pdf_codec_a85_fuzzer.cc" ]
  deps = [
    "../../core/fxcodec",
    "../../core/fxcrt",
  ]
}

pdfium_fuzzer("pdf_codec_fax_fuzzer") {
  sources = [ "pdf_codec_fax_fuzzer.cc" ]
  deps = [
    ":fuzzer_utils",
    "../../core/fxcodec",
  ]
}

pdfium_fuzzer("pdf_codec_icc_fuzzer") {
  sources = [ "pdf_codec_icc_fuzzer.cc" ]
  deps = [
    "../../core/fxcodec",
    "../../core/fxcrt",
    "../../third_party/:lcms2",
  ]
}

pdfium_fuzzer("pdf_codec_jbig2_fuzzer") {
  sources = [ "pdf_codec_jbig2_fuzzer.cc" ]
  deps = [
    ":fuzzer_utils",
    "../../core/fpdfapi/parser",
    "../../core/fxcodec",
    "../../core/fxcrt",
    "../../core/fxge",
  ]
}

pdfium_fuzzer("pdf_codec_rle_fuzzer") {
  sources = [ "pdf_codec_rle_fuzzer.cc" ]
  deps = [
    "../../core/fxcodec",
    "../../core/fxcrt",
  ]
}

pdfium_fuzzer("pdf_font_fuzzer") {
  sources = [ "pdf_font_fuzzer.cc" ]
  deps = [
    "../../:pdfium_public_headers",
    "../../core/fxcrt",
  ]
}

pdfium_fuzzer("pdf_hint_table_fuzzer") {
  sources = [ "pdf_hint_table_fuzzer.cc" ]
  deps = [
    "../../core/fpdfapi/parser",
    "../../core/fxcrt",
  ]
}

pdfium_fuzzer("pdf_jpx_fuzzer") {
  sources = [ "pdf_jpx_fuzzer.cc" ]
  deps = [
    "../../core/fpdfapi/page",
    "../../core/fxcodec",
    "../../core/fxcrt",
    "../../core/fxge",
  ]
}

pdfium_fuzzer("pdf_psengine_fuzzer") {
  sources = [ "pdf_psengine_fuzzer.cc" ]
  deps = [ "../../core/fpdfapi/page" ]
}

pdfium_fuzzer("pdf_scanlinecompositor_fuzzer") {
  sources = [ "pdf_scanlinecompositor_fuzzer.cc" ]
  deps = [
    ":fuzzer_utils",
    "../../core/fxcrt",
    "../../core/fxge",
  ]
}

pdfium_fuzzer("pdf_streamparser_fuzzer") {
  sources = [ "pdf_streamparser_fuzzer.cc" ]
  deps = [
    "../../core/fpdfapi/page",
    "../../core/fpdfapi/parser",
  ]
}

pdfium_fuzzer("pdf_xml_fuzzer") {
  sources = [ "pdf_xml_fuzzer.cc" ]
  deps = [ "../../core/fxcrt" ]
}

pdfium_fuzzer("pdfium_fuzzer") {
  sources = [ "pdfium_fuzzer.cc" ]
  deps = [ ":fuzzer_helper" ]
  public_fuzzer = true
}
