summaryrefslogtreecommitdiff
path: root/testing/fuzzers
diff options
context:
space:
mode:
Diffstat (limited to 'testing/fuzzers')
-rw-r--r--testing/fuzzers/BUILD.gn253
-rw-r--r--testing/fuzzers/DEPS3
-rw-r--r--testing/fuzzers/pdf_bidi_fuzzer.cc36
-rw-r--r--testing/fuzzers/pdf_cfx_barcode_fuzzer.cc38
-rw-r--r--testing/fuzzers/pdf_cmap_fuzzer.cc14
-rw-r--r--testing/fuzzers/pdf_codec_a85_fuzzer.cc18
-rw-r--r--testing/fuzzers/pdf_codec_bmp_fuzzer.cc9
-rw-r--r--testing/fuzzers/pdf_codec_fax_fuzzer.cc43
-rw-r--r--testing/fuzzers/pdf_codec_gif_fuzzer.cc9
-rw-r--r--testing/fuzzers/pdf_codec_icc_fuzzer.cc25
-rw-r--r--testing/fuzzers/pdf_codec_jbig2_fuzzer.cc59
-rw-r--r--testing/fuzzers/pdf_codec_jpeg_fuzzer.cc9
-rw-r--r--testing/fuzzers/pdf_codec_png_fuzzer.cc9
-rw-r--r--testing/fuzzers/pdf_codec_rle_fuzzer.cc18
-rw-r--r--testing/fuzzers/pdf_codec_tiff_fuzzer.cc9
-rw-r--r--testing/fuzzers/pdf_css_fuzzer.cc27
-rw-r--r--testing/fuzzers/pdf_fm2js_fuzzer.cc23
-rw-r--r--testing/fuzzers/pdf_font_fuzzer.cc31
-rw-r--r--testing/fuzzers/pdf_formcalc_fuzzer.cc16
-rw-r--r--testing/fuzzers/pdf_fuzzer_init.cc21
-rw-r--r--testing/fuzzers/pdf_hint_table_fuzzer.cc93
-rw-r--r--testing/fuzzers/pdf_jpx_fuzzer.cc57
-rw-r--r--testing/fuzzers/pdf_lzw_fuzzer.cc58
-rw-r--r--testing/fuzzers/pdf_psengine_fuzzer.cc15
-rw-r--r--testing/fuzzers/pdf_streamparser_fuzzer.cc19
-rw-r--r--testing/fuzzers/pdf_xml_fuzzer.cc36
-rw-r--r--testing/fuzzers/unittest_main.cc41
-rw-r--r--testing/fuzzers/xfa_codec_fuzzer.h87
28 files changed, 1076 insertions, 0 deletions
diff --git a/testing/fuzzers/BUILD.gn b/testing/fuzzers/BUILD.gn
new file mode 100644
index 0000000000..59211b1758
--- /dev/null
+++ b/testing/fuzzers/BUILD.gn
@@ -0,0 +1,253 @@
+# Copyright 2016 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.
+
+import("../../pdfium.gni")
+
+config("fuzzer_config") {
+ configs = [ "../..:pdfium_core_config" ]
+
+ defines = [
+ "PNG_PREFIX",
+ "PNG_USE_READ_MACROS",
+ ]
+ include_dirs = [ "../.." ]
+ if (pdf_enable_v8) {
+ defines += [ "PDF_ENABLE_V8" ]
+ }
+ if (pdf_enable_xfa) {
+ defines += [ "PDF_ENABLE_XFA" ]
+ }
+}
+
+group("fuzzers") {
+ testonly = true
+ deps = [
+ ":pdf_cmap_fuzzer_src",
+ ":pdf_codec_a85_fuzzer_src",
+ ":pdf_codec_fax_fuzzer_src",
+ ":pdf_codec_icc_fuzzer_src",
+ ":pdf_codec_jbig2_fuzzer_src",
+ ":pdf_codec_rle_fuzzer_src",
+ ":pdf_font_fuzzer_src",
+ ":pdf_hint_table_fuzzer_src",
+ ":pdf_jpx_fuzzer_src",
+ ":pdf_psengine_fuzzer_src",
+ ":pdf_streamparser_fuzzer_src",
+ ":pdf_xml_fuzzer_src",
+ ]
+ if (pdf_enable_xfa) {
+ deps += [
+ ":pdf_bidi_fuzzer_src",
+ ":pdf_cfx_barcode_fuzzer_src",
+ ":pdf_codec_jpeg_fuzzer_src",
+ ":pdf_css_fuzzer_src",
+ ":pdf_fm2js_fuzzer_src",
+ ":pdf_formcalc_fuzzer_src",
+ ]
+ if (pdf_enable_xfa_bmp) {
+ deps += [ ":pdf_codec_bmp_fuzzer_src" ]
+ }
+ if (pdf_enable_xfa_gif) {
+ deps += [
+ ":pdf_codec_gif_fuzzer_src",
+ ":pdf_lzw_fuzzer_src",
+ ]
+ }
+ if (pdf_enable_xfa_png) {
+ deps += [ ":pdf_codec_png_fuzzer_src" ]
+ }
+ if (pdf_enable_xfa_tiff) {
+ deps += [ ":pdf_codec_tiff_fuzzer_src" ]
+ }
+ }
+}
+
+template("pdfium_fuzzer") {
+ source_set(target_name) {
+ sources = invoker.sources + [ "pdf_fuzzer_init.cc" ]
+ deps = [
+ "../..:pdfium",
+ ]
+ if (defined(invoker.deps)) {
+ deps += invoker.deps
+ }
+ testonly = true
+ configs -= [ "//build/config/compiler:chromium_code" ]
+ configs += [
+ "//build/config/compiler:no_chromium_code",
+ ":fuzzer_config",
+ ]
+ }
+}
+
+if (pdf_enable_xfa) {
+ pdfium_fuzzer("pdf_bidi_fuzzer_src") {
+ sources = [
+ "pdf_bidi_fuzzer.cc",
+ ]
+ }
+
+ pdfium_fuzzer("pdf_cfx_barcode_fuzzer_src") {
+ sources = [
+ "pdf_cfx_barcode_fuzzer.cc",
+ ]
+ }
+
+ if (pdf_enable_xfa_bmp) {
+ pdfium_fuzzer("pdf_codec_bmp_fuzzer_src") {
+ sources = [
+ "pdf_codec_bmp_fuzzer.cc",
+ "xfa_codec_fuzzer.h",
+ ]
+ deps = [
+ "../../:test_support",
+ ]
+ }
+ }
+
+ if (pdf_enable_xfa_gif) {
+ pdfium_fuzzer("pdf_codec_gif_fuzzer_src") {
+ sources = [
+ "pdf_codec_gif_fuzzer.cc",
+ "xfa_codec_fuzzer.h",
+ ]
+ deps = [
+ "../../:test_support",
+ ]
+ }
+
+ pdfium_fuzzer("pdf_lzw_fuzzer_src") {
+ sources = [
+ "pdf_lzw_fuzzer.cc",
+ ]
+ }
+ }
+
+ pdfium_fuzzer("pdf_codec_jpeg_fuzzer_src") {
+ sources = [
+ "pdf_codec_jpeg_fuzzer.cc",
+ "xfa_codec_fuzzer.h",
+ ]
+ deps = [
+ "../../:test_support",
+ ]
+ }
+
+ if (pdf_enable_xfa_png) {
+ pdfium_fuzzer("pdf_codec_png_fuzzer_src") {
+ sources = [
+ "pdf_codec_png_fuzzer.cc",
+ "xfa_codec_fuzzer.h",
+ ]
+ deps = [
+ "../../:test_support",
+ ]
+ }
+ }
+
+ if (pdf_enable_xfa_tiff) {
+ pdfium_fuzzer("pdf_codec_tiff_fuzzer_src") {
+ sources = [
+ "pdf_codec_tiff_fuzzer.cc",
+ "xfa_codec_fuzzer.h",
+ ]
+ deps = [
+ "../../:test_support",
+ ]
+ }
+ }
+
+ pdfium_fuzzer("pdf_css_fuzzer_src") {
+ sources = [
+ "pdf_css_fuzzer.cc",
+ ]
+ }
+
+ pdfium_fuzzer("pdf_fm2js_fuzzer_src") {
+ sources = [
+ "pdf_fm2js_fuzzer.cc",
+ ]
+ }
+
+ pdfium_fuzzer("pdf_formcalc_fuzzer_src") {
+ sources = [
+ "pdf_formcalc_fuzzer.cc",
+ ]
+ }
+}
+
+pdfium_fuzzer("pdf_cmap_fuzzer_src") {
+ sources = [
+ "pdf_cmap_fuzzer.cc",
+ ]
+}
+
+pdfium_fuzzer("pdf_codec_a85_fuzzer_src") {
+ sources = [
+ "pdf_codec_a85_fuzzer.cc",
+ ]
+}
+
+pdfium_fuzzer("pdf_codec_fax_fuzzer_src") {
+ sources = [
+ "pdf_codec_fax_fuzzer.cc",
+ ]
+}
+
+pdfium_fuzzer("pdf_codec_icc_fuzzer_src") {
+ deps = [
+ "../../third_party/:lcms2",
+ ]
+ sources = [
+ "pdf_codec_icc_fuzzer.cc",
+ ]
+}
+
+pdfium_fuzzer("pdf_codec_jbig2_fuzzer_src") {
+ sources = [
+ "pdf_codec_jbig2_fuzzer.cc",
+ ]
+}
+
+pdfium_fuzzer("pdf_codec_rle_fuzzer_src") {
+ sources = [
+ "pdf_codec_rle_fuzzer.cc",
+ ]
+}
+
+pdfium_fuzzer("pdf_font_fuzzer_src") {
+ sources = [
+ "pdf_font_fuzzer.cc",
+ ]
+}
+
+pdfium_fuzzer("pdf_hint_table_fuzzer_src") {
+ sources = [
+ "pdf_hint_table_fuzzer.cc",
+ ]
+}
+
+pdfium_fuzzer("pdf_jpx_fuzzer_src") {
+ sources = [
+ "pdf_jpx_fuzzer.cc",
+ ]
+}
+
+pdfium_fuzzer("pdf_psengine_fuzzer_src") {
+ sources = [
+ "pdf_psengine_fuzzer.cc",
+ ]
+}
+
+pdfium_fuzzer("pdf_streamparser_fuzzer_src") {
+ sources = [
+ "pdf_streamparser_fuzzer.cc",
+ ]
+}
+
+pdfium_fuzzer("pdf_xml_fuzzer_src") {
+ sources = [
+ "pdf_xml_fuzzer.cc",
+ ]
+}
diff --git a/testing/fuzzers/DEPS b/testing/fuzzers/DEPS
new file mode 100644
index 0000000000..b1d034ed8c
--- /dev/null
+++ b/testing/fuzzers/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ '+xfa',
+]
diff --git a/testing/fuzzers/pdf_bidi_fuzzer.cc b/testing/fuzzers/pdf_bidi_fuzzer.cc
new file mode 100644
index 0000000000..8e52688a10
--- /dev/null
+++ b/testing/fuzzers/pdf_bidi_fuzzer.cc
@@ -0,0 +1,36 @@
+// Copyright 2018 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 <cstdint>
+
+#include "core/fxcrt/fx_bidi.h"
+#include "core/fxcrt/widestring.h"
+#include "core/fxge/cfx_font.h"
+#include "third_party/base/span.h"
+#include "xfa/fgas/font/cfgas_fontmgr.h"
+#include "xfa/fgas/font/cfgas_gefont.h"
+#include "xfa/fgas/layout/cfx_rtfbreak.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ auto fontmgr = pdfium::MakeUnique<CFGAS_FontMgr>();
+
+ auto font = pdfium::MakeUnique<CFX_Font>();
+ font->LoadSubst("Arial", true, 0, FXFONT_FW_NORMAL, 0, 0, 0);
+ assert(font);
+
+ CFX_RTFBreak rtf_break(FX_LAYOUTSTYLE_ExpandTab);
+ rtf_break.SetLineBreakTolerance(1);
+ rtf_break.SetFont(CFGAS_GEFont::LoadFont(std::move(font), fontmgr.get()));
+ rtf_break.SetFontSize(12);
+
+ WideString input =
+ WideString::FromUTF16LE(reinterpret_cast<const unsigned short*>(data),
+ size / sizeof(unsigned short));
+ for (auto& ch : input)
+ rtf_break.AppendChar(ch);
+
+ auto chars = rtf_break.GetCurrentLineForTesting()->m_LineChars;
+ FX_BidiLine(&chars, chars.size());
+ return 0;
+}
diff --git a/testing/fuzzers/pdf_cfx_barcode_fuzzer.cc b/testing/fuzzers/pdf_cfx_barcode_fuzzer.cc
new file mode 100644
index 0000000000..aaeebf3ace
--- /dev/null
+++ b/testing/fuzzers/pdf_cfx_barcode_fuzzer.cc
@@ -0,0 +1,38 @@
+// Copyright 2017 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 <memory>
+
+#include "core/fxcrt/fx_string.h"
+#include "xfa/fwl/cfx_barcode.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if (size < 2 * sizeof(wchar_t))
+ return 0;
+
+ BC_TYPE type = static_cast<BC_TYPE>(data[0] % (BC_DATAMATRIX + 1));
+
+ // Only used one byte, but align with wchar_t for string below.
+ data += sizeof(wchar_t);
+ size -= sizeof(wchar_t);
+
+ auto barcode = CFX_Barcode::Create(type);
+ if (!barcode)
+ return 0;
+
+ // TODO(tsepez): Setup more options from |data|.
+ barcode->SetModuleHeight(300);
+ barcode->SetModuleWidth(420);
+ barcode->SetHeight(298);
+ barcode->SetWidth(418);
+
+ WideStringView content(reinterpret_cast<const wchar_t*>(data),
+ size / sizeof(wchar_t));
+
+ if (!barcode->Encode(content))
+ return 0;
+
+ // TODO(tsepez): Output to device.
+ return 0;
+}
diff --git a/testing/fuzzers/pdf_cmap_fuzzer.cc b/testing/fuzzers/pdf_cmap_fuzzer.cc
new file mode 100644
index 0000000000..0c0ff11f36
--- /dev/null
+++ b/testing/fuzzers/pdf_cmap_fuzzer.cc
@@ -0,0 +1,14 @@
+// Copyright 2016 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 <cstdint>
+
+#include "core/fpdfapi/font/cpdf_cmap.h"
+#include "third_party/base/ptr_util.h"
+#include "third_party/base/span.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ pdfium::MakeRetain<CPDF_CMap>()->LoadEmbedded(pdfium::make_span(data, size));
+ return 0;
+}
diff --git a/testing/fuzzers/pdf_codec_a85_fuzzer.cc b/testing/fuzzers/pdf_codec_a85_fuzzer.cc
new file mode 100644
index 0000000000..20bd792886
--- /dev/null
+++ b/testing/fuzzers/pdf_codec_a85_fuzzer.cc
@@ -0,0 +1,18 @@
+// Copyright 2017 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 <cstdint>
+#include <memory>
+
+#include "core/fxcodec/codec/ccodec_basicmodule.h"
+#include "core/fxcrt/fx_memory.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ uint8_t* dest_buf = nullptr;
+ uint32_t dest_size = 0;
+ CCodec_BasicModule encoder_module;
+ encoder_module.A85Encode(data, size, &dest_buf, &dest_size);
+ FX_Free(dest_buf);
+ return 0;
+}
diff --git a/testing/fuzzers/pdf_codec_bmp_fuzzer.cc b/testing/fuzzers/pdf_codec_bmp_fuzzer.cc
new file mode 100644
index 0000000000..71f9150f5c
--- /dev/null
+++ b/testing/fuzzers/pdf_codec_bmp_fuzzer.cc
@@ -0,0 +1,9 @@
+// Copyright 2016 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 "testing/fuzzers/xfa_codec_fuzzer.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ return XFACodecFuzzer::Fuzz(data, size, FXCODEC_IMAGE_BMP);
+}
diff --git a/testing/fuzzers/pdf_codec_fax_fuzzer.cc b/testing/fuzzers/pdf_codec_fax_fuzzer.cc
new file mode 100644
index 0000000000..f6cc1e7200
--- /dev/null
+++ b/testing/fuzzers/pdf_codec_fax_fuzzer.cc
@@ -0,0 +1,43 @@
+// Copyright 2016 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 <cstdint>
+#include <memory>
+
+#include "core/fxcodec/codec/ccodec_faxmodule.h"
+#include "core/fxcodec/codec/ccodec_scanlinedecoder.h"
+
+static int GetInteger(const uint8_t* data) {
+ return data[0] | data[1] << 8 | data[2] << 16 | data[3] << 24;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ const int kParameterSize = 21;
+ if (size < kParameterSize)
+ return 0;
+
+ int width = GetInteger(data);
+ int height = GetInteger(data + 4);
+ int K = GetInteger(data + 8);
+ int Columns = GetInteger(data + 12);
+ int Rows = GetInteger(data + 16);
+ bool EndOfLine = !(data[20] & 0x01);
+ bool ByteAlign = !(data[20] & 0x02);
+ bool BlackIs1 = !(data[20] & 0x04);
+ data += kParameterSize;
+ size -= kParameterSize;
+
+ CCodec_FaxModule fax_module;
+ std::unique_ptr<CCodec_ScanlineDecoder> decoder(
+ fax_module.CreateDecoder(data, size, width, height, K, EndOfLine,
+ ByteAlign, BlackIs1, Columns, Rows));
+
+ if (decoder) {
+ int line = 0;
+ while (decoder->GetScanline(line))
+ line++;
+ }
+
+ return 0;
+}
diff --git a/testing/fuzzers/pdf_codec_gif_fuzzer.cc b/testing/fuzzers/pdf_codec_gif_fuzzer.cc
new file mode 100644
index 0000000000..69129e7068
--- /dev/null
+++ b/testing/fuzzers/pdf_codec_gif_fuzzer.cc
@@ -0,0 +1,9 @@
+// Copyright 2016 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 "testing/fuzzers/xfa_codec_fuzzer.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ return XFACodecFuzzer::Fuzz(data, size, FXCODEC_IMAGE_GIF);
+}
diff --git a/testing/fuzzers/pdf_codec_icc_fuzzer.cc b/testing/fuzzers/pdf_codec_icc_fuzzer.cc
new file mode 100644
index 0000000000..7021017953
--- /dev/null
+++ b/testing/fuzzers/pdf_codec_icc_fuzzer.cc
@@ -0,0 +1,25 @@
+// Copyright 2016 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 <cstdint>
+
+#include "core/fxcodec/codec/ccodec_iccmodule.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ CCodec_IccModule icc_module;
+ uint32_t nComponent = 0;
+ std::unique_ptr<CLcmsCmm> transform =
+ icc_module.CreateTransform_sRGB(data, size, &nComponent);
+
+ if (transform) {
+ float src[4];
+ float dst[4];
+ for (int i = 0; i < 4; i++)
+ src[i] = 0.5f;
+ icc_module.SetComponents(nComponent);
+ icc_module.Translate(transform.get(), src, dst);
+ }
+
+ return 0;
+}
diff --git a/testing/fuzzers/pdf_codec_jbig2_fuzzer.cc b/testing/fuzzers/pdf_codec_jbig2_fuzzer.cc
new file mode 100644
index 0000000000..7b8e2aac33
--- /dev/null
+++ b/testing/fuzzers/pdf_codec_jbig2_fuzzer.cc
@@ -0,0 +1,59 @@
+// Copyright 2016 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 <cstdint>
+
+#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfapi/parser/cpdf_stream_acc.h"
+#include "core/fxcodec/JBig2_DocumentContext.h"
+#include "core/fxcodec/codec/ccodec_jbig2module.h"
+#include "core/fxcodec/jbig2/JBig2_Context.h"
+#include "core/fxcrt/fx_safe_types.h"
+#include "core/fxge/dib/cfx_dibitmap.h"
+#include "core/fxge/fx_dib.h"
+#include "third_party/base/ptr_util.h"
+
+static uint32_t GetInteger(const uint8_t* data) {
+ return data[0] | data[1] << 8 | data[2] << 16 | data[3] << 24;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ const size_t kParameterSize = 8;
+ if (size < kParameterSize)
+ return 0;
+
+ uint32_t width = GetInteger(data);
+ uint32_t height = GetInteger(data + 4);
+ size -= kParameterSize;
+ data += kParameterSize;
+
+ static constexpr uint32_t kMemLimit = 512000000; // 512 MB
+ static constexpr uint32_t k1bppRgbComponents = 4; // From CFX_DIBitmap impl.
+ FX_SAFE_UINT32 mem = width;
+ mem *= height;
+ mem *= k1bppRgbComponents;
+ if (!mem.IsValid() || mem.ValueOrDie() > kMemLimit)
+ return 0;
+
+ auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
+ if (!bitmap->Create(width, height, FXDIB_1bppRgb))
+ return 0;
+
+ auto stream = pdfium::MakeUnique<CPDF_Stream>();
+ stream->AsStream()->SetData(data, size);
+
+ auto src_stream = pdfium::MakeRetain<CPDF_StreamAcc>(stream->AsStream());
+ src_stream->LoadAllDataRaw();
+
+ CCodec_Jbig2Module module;
+ CCodec_Jbig2Context jbig2_context;
+ std::unique_ptr<JBig2_DocumentContext> document_context;
+ FXCODEC_STATUS status = module.StartDecode(
+ &jbig2_context, &document_context, width, height, src_stream, nullptr,
+ bitmap->GetBuffer(), bitmap->GetPitch(), nullptr);
+
+ while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE)
+ status = module.ContinueDecode(&jbig2_context, nullptr);
+ return 0;
+}
diff --git a/testing/fuzzers/pdf_codec_jpeg_fuzzer.cc b/testing/fuzzers/pdf_codec_jpeg_fuzzer.cc
new file mode 100644
index 0000000000..eaa0889e3c
--- /dev/null
+++ b/testing/fuzzers/pdf_codec_jpeg_fuzzer.cc
@@ -0,0 +1,9 @@
+// Copyright 2016 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 "testing/fuzzers/xfa_codec_fuzzer.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ return XFACodecFuzzer::Fuzz(data, size, FXCODEC_IMAGE_JPG);
+}
diff --git a/testing/fuzzers/pdf_codec_png_fuzzer.cc b/testing/fuzzers/pdf_codec_png_fuzzer.cc
new file mode 100644
index 0000000000..61a65748fe
--- /dev/null
+++ b/testing/fuzzers/pdf_codec_png_fuzzer.cc
@@ -0,0 +1,9 @@
+// Copyright 2016 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 "testing/fuzzers/xfa_codec_fuzzer.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ return XFACodecFuzzer::Fuzz(data, size, FXCODEC_IMAGE_PNG);
+}
diff --git a/testing/fuzzers/pdf_codec_rle_fuzzer.cc b/testing/fuzzers/pdf_codec_rle_fuzzer.cc
new file mode 100644
index 0000000000..c86671e5f4
--- /dev/null
+++ b/testing/fuzzers/pdf_codec_rle_fuzzer.cc
@@ -0,0 +1,18 @@
+// Copyright 2017 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 <cstdint>
+#include <memory>
+
+#include "core/fxcodec/codec/ccodec_basicmodule.h"
+#include "core/fxcrt/fx_memory.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ uint8_t* dest_buf = nullptr;
+ uint32_t dest_size = 0;
+ CCodec_BasicModule encoder_module;
+ encoder_module.RunLengthEncode(data, size, &dest_buf, &dest_size);
+ FX_Free(dest_buf);
+ return 0;
+}
diff --git a/testing/fuzzers/pdf_codec_tiff_fuzzer.cc b/testing/fuzzers/pdf_codec_tiff_fuzzer.cc
new file mode 100644
index 0000000000..187c311fc7
--- /dev/null
+++ b/testing/fuzzers/pdf_codec_tiff_fuzzer.cc
@@ -0,0 +1,9 @@
+// Copyright 2016 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 "testing/fuzzers/xfa_codec_fuzzer.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ return XFACodecFuzzer::Fuzz(data, size, FXCODEC_IMAGE_TIFF);
+}
diff --git a/testing/fuzzers/pdf_css_fuzzer.cc b/testing/fuzzers/pdf_css_fuzzer.cc
new file mode 100644
index 0000000000..4f2f410aa3
--- /dev/null
+++ b/testing/fuzzers/pdf_css_fuzzer.cc
@@ -0,0 +1,27 @@
+// Copyright 2016 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 <memory>
+
+#include "core/fxcrt/css/cfx_css.h"
+#include "core/fxcrt/css/cfx_csssyntaxparser.h"
+#include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/retain_ptr.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ WideString input =
+ WideString::FromUTF8(ByteStringView(data, static_cast<size_t>(size)));
+
+ // If we convert the input into an empty string bail out.
+ if (input.GetLength() == 0)
+ return 0;
+
+ CFX_CSSSyntaxParser parser(input.c_str(), input.GetLength());
+ CFX_CSSSyntaxStatus status;
+ do {
+ status = parser.DoSyntaxParse();
+ } while (status != CFX_CSSSyntaxStatus::Error &&
+ status != CFX_CSSSyntaxStatus::EOS);
+ return 0;
+}
diff --git a/testing/fuzzers/pdf_fm2js_fuzzer.cc b/testing/fuzzers/pdf_fm2js_fuzzer.cc
new file mode 100644
index 0000000000..2541dfbcc8
--- /dev/null
+++ b/testing/fuzzers/pdf_fm2js_fuzzer.cc
@@ -0,0 +1,23 @@
+// Copyright 2016 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 <cstddef>
+#include <cstdint>
+
+#include "core/fxcrt/cfx_widetextbuf.h"
+#include "core/fxcrt/fx_safe_types.h"
+#include "core/fxcrt/fx_string.h"
+#include "fxjs/cfxjse_formcalc_context.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FX_SAFE_SIZE_T safe_size = size;
+ if (!safe_size.IsValid())
+ return 0;
+
+ CFX_WideTextBuf js;
+ WideString input =
+ WideString::FromUTF8(ByteStringView(data, safe_size.ValueOrDie()));
+ CFXJSE_FormCalcContext::Translate(input.AsStringView(), &js);
+ return 0;
+}
diff --git a/testing/fuzzers/pdf_font_fuzzer.cc b/testing/fuzzers/pdf_font_fuzzer.cc
new file mode 100644
index 0000000000..7c596307f0
--- /dev/null
+++ b/testing/fuzzers/pdf_font_fuzzer.cc
@@ -0,0 +1,31 @@
+// Copyright 2017 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 <cstring>
+#include <memory>
+
+#include "public/cpp/fpdf_scopers.h"
+#include "public/fpdf_edit.h"
+#include "public/fpdfview.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if (size < 2)
+ return 0;
+
+ ScopedFPDFDocument doc(FPDF_CreateNewDocument());
+ ScopedFPDFPage page(FPDFPage_New(doc.get(), 0, 612, 792));
+ int font_type = data[0];
+ FPDF_BOOL cid = data[1];
+ data += 2;
+ size -= 2;
+ ScopedFPDFFont font(FPDFText_LoadFont(doc.get(), data, size, font_type, cid));
+ if (!font)
+ return 0;
+
+ FPDF_PAGEOBJECT text_object =
+ FPDFPageObj_CreateTextObj(doc.get(), font.get(), 12.0f);
+ FPDFPage_InsertObject(page.get(), text_object);
+ FPDFPage_GenerateContent(page.get());
+ return 0;
+}
diff --git a/testing/fuzzers/pdf_formcalc_fuzzer.cc b/testing/fuzzers/pdf_formcalc_fuzzer.cc
new file mode 100644
index 0000000000..08e22bb247
--- /dev/null
+++ b/testing/fuzzers/pdf_formcalc_fuzzer.cc
@@ -0,0 +1,16 @@
+// Copyright 2017 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 "core/fxcrt/cfx_widetextbuf.h"
+#include "core/fxcrt/fx_string.h"
+#include "xfa/fxfa/fm2js/cxfa_fmparser.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ WideString input = WideString::FromUTF8(ByteStringView(data, size));
+
+ CXFA_FMParser parser(input.AsStringView());
+ parser.Parse();
+
+ return 0;
+}
diff --git a/testing/fuzzers/pdf_fuzzer_init.cc b/testing/fuzzers/pdf_fuzzer_init.cc
new file mode 100644
index 0000000000..4b9790c3f8
--- /dev/null
+++ b/testing/fuzzers/pdf_fuzzer_init.cc
@@ -0,0 +1,21 @@
+// Copyright 2017 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 <string.h>
+
+#include "public/fpdfview.h"
+
+// Initialize the library once for all runs of the fuzzer.
+struct TestCase {
+ TestCase() {
+ memset(&config, '\0', sizeof(config));
+ config.version = 2;
+ config.m_pUserFontPaths = nullptr;
+ config.m_pIsolate = nullptr;
+ config.m_v8EmbedderSlot = 0;
+ FPDF_InitLibraryWithConfig(&config);
+ }
+ FPDF_LIBRARY_CONFIG config;
+};
+static TestCase* testCase = new TestCase();
diff --git a/testing/fuzzers/pdf_hint_table_fuzzer.cc b/testing/fuzzers/pdf_hint_table_fuzzer.cc
new file mode 100644
index 0000000000..50ca5cd693
--- /dev/null
+++ b/testing/fuzzers/pdf_hint_table_fuzzer.cc
@@ -0,0 +1,93 @@
+// Copyright 2016 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 <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/ptr_util.h"
+#include "third_party/base/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 : 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() {}
+
+ 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 : 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::MakeUnique<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::MakeUnique<CPDF_Array>();
+ // Add primary hint stream offset
+ hint_info->AddNew<CPDF_Number>(GetData(&data32, &data, &size));
+ // Add primary hint stream size
+ hint_info->AddNew<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;
+}
diff --git a/testing/fuzzers/pdf_jpx_fuzzer.cc b/testing/fuzzers/pdf_jpx_fuzzer.cc
new file mode 100644
index 0000000000..da65bc2d9a
--- /dev/null
+++ b/testing/fuzzers/pdf_jpx_fuzzer.cc
@@ -0,0 +1,57 @@
+// Copyright 2016 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 <cstdint>
+#include <memory>
+#include <vector>
+
+#include "core/fxcodec/codec/ccodec_jpxmodule.h"
+#include "core/fxcodec/codec/cjpx_decoder.h"
+#include "core/fxcrt/fx_safe_types.h"
+#include "core/fxge/dib/cfx_dibitmap.h"
+#include "core/fxge/fx_dib.h"
+
+CCodec_JpxModule g_module;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ std::unique_ptr<CJPX_Decoder> decoder =
+ g_module.CreateDecoder(data, size, nullptr);
+ if (!decoder)
+ return 0;
+
+ uint32_t width;
+ uint32_t height;
+ uint32_t components;
+ g_module.GetImageInfo(decoder.get(), &width, &height, &components);
+
+ static constexpr uint32_t kMemLimit = 1024 * 1024 * 1024; // 1 GB.
+ FX_SAFE_UINT32 mem = width;
+ mem *= height;
+ mem *= components;
+ if (!mem.IsValid() || mem.ValueOrDie() > kMemLimit)
+ return 0;
+
+ FXDIB_Format format;
+ if (components == 1) {
+ format = FXDIB_8bppRgb;
+ } else if (components <= 3) {
+ format = FXDIB_Rgb;
+ } else if (components == 4) {
+ format = FXDIB_Rgb32;
+ } else {
+ width = (width * components + 2) / 3;
+ format = FXDIB_Rgb;
+ }
+ auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
+ if (!bitmap->Create(width, height, format))
+ return 0;
+
+ std::vector<uint8_t> output_offsets(components);
+ for (uint32_t i = 0; i < components; ++i)
+ output_offsets[i] = i;
+
+ g_module.Decode(decoder.get(), bitmap->GetBuffer(), bitmap->GetPitch(),
+ output_offsets);
+ return 0;
+}
diff --git a/testing/fuzzers/pdf_lzw_fuzzer.cc b/testing/fuzzers/pdf_lzw_fuzzer.cc
new file mode 100644
index 0000000000..7e10d2a1ee
--- /dev/null
+++ b/testing/fuzzers/pdf_lzw_fuzzer.cc
@@ -0,0 +1,58 @@
+// Copyright 2017 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 <vector>
+
+#include "core/fxcodec/gif/cfx_lzwdecompressor.h"
+#include "third_party/base/numerics/safe_conversions.h"
+
+// Between 2x and 5x is a standard range for LZW according to a quick
+// search of papers. Running up to 10x to catch any niche cases.
+constexpr uint32_t kMinCompressionRatio = 2;
+constexpr uint32_t kMaxCompressionRatio = 10;
+
+void LZWFuzz(const uint8_t* src_buf,
+ size_t src_size,
+ uint8_t color_exp,
+ uint8_t code_exp) {
+ std::unique_ptr<CFX_LZWDecompressor> decompressor =
+ CFX_LZWDecompressor::Create(color_exp, code_exp);
+ if (!decompressor)
+ return;
+
+ for (uint32_t compressions_ratio = kMinCompressionRatio;
+ compressions_ratio <= kMaxCompressionRatio; compressions_ratio++) {
+ std::vector<uint8_t> dest_buf(compressions_ratio * src_size);
+ // This cast should be safe since the caller is checking for overflow on
+ // the initial data.
+ uint32_t dest_size = static_cast<uint32_t>(dest_buf.size());
+ if (CFX_GifDecodeStatus::InsufficientDestSize !=
+ decompressor->Decode(const_cast<uint8_t*>(src_buf), src_size,
+ dest_buf.data(), &dest_size))
+ return;
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ // Need at least 3 bytes to do anything.
+ if (size < 3)
+ return 0;
+
+ // Normally the GIF would provide the code and color sizes, instead, going
+ // to assume they are the first two bytes of data provided.
+ uint8_t color_exp = data[0];
+ uint8_t code_exp = data[1];
+ const uint8_t* lzw_data = data + 2;
+ uint32_t lzw_data_size = static_cast<uint32_t>(size - 2);
+ // Check that there isn't going to be an overflow in the destination buffer
+ // size.
+ if (lzw_data_size >
+ std::numeric_limits<uint32_t>::max() / kMaxCompressionRatio) {
+ return 0;
+ }
+
+ LZWFuzz(lzw_data, lzw_data_size, color_exp, code_exp);
+
+ return 0;
+}
diff --git a/testing/fuzzers/pdf_psengine_fuzzer.cc b/testing/fuzzers/pdf_psengine_fuzzer.cc
new file mode 100644
index 0000000000..d72088d4e3
--- /dev/null
+++ b/testing/fuzzers/pdf_psengine_fuzzer.cc
@@ -0,0 +1,15 @@
+// Copyright 2016 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 <cstdint>
+
+#include "core/fpdfapi/page/cpdf_psengine.h"
+#include "third_party/base/span.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ CPDF_PSEngine engine;
+ if (engine.Parse(pdfium::make_span(data, size)))
+ engine.Execute();
+ return 0;
+}
diff --git a/testing/fuzzers/pdf_streamparser_fuzzer.cc b/testing/fuzzers/pdf_streamparser_fuzzer.cc
new file mode 100644
index 0000000000..4d9a368916
--- /dev/null
+++ b/testing/fuzzers/pdf_streamparser_fuzzer.cc
@@ -0,0 +1,19 @@
+// Copyright 2016 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 <cstdint>
+#include <memory>
+
+#include "core/fpdfapi/page/cpdf_streamparser.h"
+#include "core/fpdfapi/parser/cpdf_object.h"
+#include "third_party/base/span.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ CPDF_StreamParser parser(pdfium::make_span(data, size));
+ while (std::unique_ptr<CPDF_Object> pObj =
+ parser.ReadNextObject(true, false, 0))
+ continue;
+
+ return 0;
+}
diff --git a/testing/fuzzers/pdf_xml_fuzzer.cc b/testing/fuzzers/pdf_xml_fuzzer.cc
new file mode 100644
index 0000000000..a3c399f78d
--- /dev/null
+++ b/testing/fuzzers/pdf_xml_fuzzer.cc
@@ -0,0 +1,36 @@
+// Copyright 2016 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 <cstddef>
+#include <cstdint>
+#include <memory>
+
+#include "core/fxcrt/cfx_memorystream.h"
+#include "core/fxcrt/fx_safe_types.h"
+#include "core/fxcrt/fx_system.h"
+#include "core/fxcrt/xml/cfx_xmldocument.h"
+#include "core/fxcrt/xml/cfx_xmlelement.h"
+#include "core/fxcrt/xml/cfx_xmlparser.h"
+#include "third_party/base/ptr_util.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FX_SAFE_SIZE_T safe_size = size;
+ if (!safe_size.IsValid())
+ return 0;
+
+ auto stream = pdfium::MakeRetain<CFX_MemoryStream>(const_cast<uint8_t*>(data),
+ size, false);
+
+ CFX_XMLParser parser(stream);
+ std::unique_ptr<CFX_XMLDocument> doc = parser.Parse();
+ if (!doc || !doc->GetRoot())
+ return 0;
+
+ for (CFX_XMLNode* pXMLNode = doc->GetRoot()->GetFirstChild(); pXMLNode;
+ pXMLNode = pXMLNode->GetNextSibling()) {
+ if (pXMLNode->GetType() == FX_XMLNODE_Element)
+ break;
+ }
+ return 0;
+}
diff --git a/testing/fuzzers/unittest_main.cc b/testing/fuzzers/unittest_main.cc
new file mode 100644
index 0000000000..f6b29e483f
--- /dev/null
+++ b/testing/fuzzers/unittest_main.cc
@@ -0,0 +1,41 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A simple unit-test style driver for libfuzzer tests.
+// Usage: <fuzzer_test> <file>...
+
+#include <fstream>
+#include <iostream>
+#include <iterator>
+#include <vector>
+
+// Libfuzzer API.
+extern "C" {
+// User function.
+int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size);
+// Initialization function.
+__attribute__((weak)) int LLVMFuzzerInitialize(int* argc, char*** argv);
+}
+
+std::vector<char> readFile(std::string path) {
+ std::ifstream in(path);
+ return std::vector<char>((std::istreambuf_iterator<char>(in)),
+ std::istreambuf_iterator<char>());
+}
+
+int main(int argc, char** argv) {
+ if (argc == 1) {
+ std::cerr << "Usage: " << argv[0] << " <file>..." << std::endl;
+ exit(1);
+ }
+
+ if (LLVMFuzzerInitialize)
+ LLVMFuzzerInitialize(&argc, &argv);
+
+ for (int i = 1; i < argc; ++i) {
+ std::cout << argv[i] << std::endl;
+ auto v = readFile(argv[i]);
+ LLVMFuzzerTestOneInput((const unsigned char*)v.data(), v.size());
+ }
+}
diff --git a/testing/fuzzers/xfa_codec_fuzzer.h b/testing/fuzzers/xfa_codec_fuzzer.h
new file mode 100644
index 0000000000..bfc069a31d
--- /dev/null
+++ b/testing/fuzzers/xfa_codec_fuzzer.h
@@ -0,0 +1,87 @@
+// Copyright 2016 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.
+
+#ifndef TESTING_FUZZERS_XFA_CODEC_FUZZER_H_
+#define TESTING_FUZZERS_XFA_CODEC_FUZZER_H_
+
+#include <memory>
+
+#include "core/fxcodec/codec/ccodec_progressivedecoder.h"
+#include "core/fxcodec/fx_codec.h"
+#include "core/fxge/dib/cfx_dibitmap.h"
+#include "testing/fx_string_testhelpers.h"
+#include "third_party/base/ptr_util.h"
+
+#ifdef PDF_ENABLE_XFA_BMP
+#include "core/fxcodec/codec/ccodec_bmpmodule.h"
+#endif // PDF_ENABLE_XFA_BMP
+
+#ifdef PDF_ENABLE_XFA_GIF
+#include "core/fxcodec/codec/ccodec_gifmodule.h"
+#endif // PDF_ENABLE_XFA_GIF
+
+#ifdef PDF_ENABLE_XFA_PNG
+#include "core/fxcodec/codec/ccodec_pngmodule.h"
+#endif // PDF_ENABLE_XFA_PNG
+
+#ifdef PDF_ENABLE_XFA_TIFF
+#include "core/fxcodec/codec/ccodec_tiffmodule.h"
+#endif // PDF_ENABLE_XFA_TIFF
+
+// Support up to 64 MB. This prevents trivial OOM when MSAN is on and
+// time outs.
+const int kXFACodecFuzzerPixelLimit = 64000000;
+
+class XFACodecFuzzer {
+ public:
+ static int Fuzz(const uint8_t* data, size_t size, FXCODEC_IMAGE_TYPE type) {
+ auto mgr = pdfium::MakeUnique<CCodec_ModuleMgr>();
+#ifdef PDF_ENABLE_XFA_BMP
+ mgr->SetBmpModule(pdfium::MakeUnique<CCodec_BmpModule>());
+#endif // PDF_ENABLE_XFA_BMP
+#ifdef PDF_ENABLE_XFA_GIF
+ mgr->SetGifModule(pdfium::MakeUnique<CCodec_GifModule>());
+#endif // PDF_ENABLE_XFA_GIF
+#ifdef PDF_ENABLE_XFA_PNG
+ mgr->SetPngModule(pdfium::MakeUnique<CCodec_PngModule>());
+#endif // PDF_ENABLE_XFA_PNG
+#ifdef PDF_ENABLE_XFA_TIFF
+ mgr->SetTiffModule(pdfium::MakeUnique<CCodec_TiffModule>());
+#endif // PDF_ENABLE_XFA_TIFF
+
+ std::unique_ptr<CCodec_ProgressiveDecoder> decoder =
+ mgr->CreateProgressiveDecoder();
+ auto source = pdfium::MakeRetain<CFX_BufferSeekableReadStream>(data, size);
+ FXCODEC_STATUS status = decoder->LoadImageInfo(source, type, nullptr, true);
+ if (status != FXCODEC_STATUS_FRAME_READY)
+ return 0;
+
+ // Skipping very large images, since they will take a long time and may lead
+ // to OOM.
+ FX_SAFE_UINT32 bitmap_size = decoder->GetHeight();
+ bitmap_size *= decoder->GetWidth();
+ bitmap_size *= 4; // From CFX_DIBitmap impl.
+ if (!bitmap_size.IsValid() ||
+ bitmap_size.ValueOrDie() > kXFACodecFuzzerPixelLimit) {
+ return 0;
+ }
+
+ auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
+ bitmap->Create(decoder->GetWidth(), decoder->GetHeight(), FXDIB_Argb);
+
+ size_t frames;
+ std::tie(status, frames) = decoder->GetFrames();
+ if (status != FXCODEC_STATUS_DECODE_READY || frames == 0)
+ return 0;
+
+ status = decoder->StartDecode(bitmap, 0, 0, bitmap->GetWidth(),
+ bitmap->GetHeight());
+ while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE)
+ status = decoder->ContinueDecode();
+
+ return 0;
+ }
+};
+
+#endif // TESTING_FUZZERS_XFA_CODEC_FUZZER_H_