Add a fuzzer for the public methods of CFX_ScanlineCompositor.
The public methods for CFX_ScanlineCompositor are exercised through
callers CFX_DIBitmap::CompositeMask() and
CFX_DIBitmap::CompositeBitmap().
Change-Id: I386bbab5ae6f2ff262246cfe12bec98a5806ba2b
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/61490
Commit-Queue: Hui Yingst <nigi@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxge/fx_dib.h b/core/fxge/fx_dib.h
index c292e99..e16957c 100644
--- a/core/fxge/fx_dib.h
+++ b/core/fxge/fx_dib.h
@@ -78,6 +78,7 @@
kSaturation,
kColor,
kLuminosity,
+ kLast = kLuminosity,
};
constexpr uint32_t FXSYS_BGR(uint8_t b, uint8_t g, uint8_t r) {
diff --git a/testing/fuzzers/BUILD.gn b/testing/fuzzers/BUILD.gn
index dccf6b6..c890469 100644
--- a/testing/fuzzers/BUILD.gn
+++ b/testing/fuzzers/BUILD.gn
@@ -27,6 +27,7 @@
"pdf_hint_table_fuzzer",
"pdf_jpx_fuzzer",
"pdf_psengine_fuzzer",
+ "pdf_scanlinecompositor_fuzzer",
"pdf_streamparser_fuzzer",
"pdf_xml_fuzzer",
"pdfium_fuzzer",
@@ -539,6 +540,17 @@
]
}
+pdfium_fuzzer("pdf_scanlinecompositor_fuzzer") {
+ sources = [
+ "pdf_scanlinecompositor_fuzzer.cc",
+ ]
+ deps = [
+ ":fuzzer_utils",
+ "../../core/fxge",
+ "../../third_party:pdfium_base",
+ ]
+}
+
pdfium_fuzzer("pdf_streamparser_fuzzer") {
sources = [
"pdf_streamparser_fuzzer.cc",
diff --git a/testing/fuzzers/pdf_scanlinecompositor_fuzzer.cc b/testing/fuzzers/pdf_scanlinecompositor_fuzzer.cc
new file mode 100644
index 0000000..4b20068
--- /dev/null
+++ b/testing/fuzzers/pdf_scanlinecompositor_fuzzer.cc
@@ -0,0 +1,66 @@
+// Copyright 2019 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/fxge/cfx_cliprgn.h"
+#include "core/fxge/dib/cfx_dibitmap.h"
+#include "core/fxge/fx_dib.h"
+#include "testing/fuzzers/pdfium_fuzzer_util.h"
+#include "third_party/base/ptr_util.h"
+
+namespace {
+
+constexpr FXDIB_Format kFormat[] = {
+ FXDIB_Invalid, FXDIB_1bppRgb, FXDIB_8bppRgb, FXDIB_Rgb,
+ FXDIB_Rgb32, FXDIB_1bppMask, FXDIB_8bppMask, FXDIB_8bppRgba,
+ FXDIB_Rgba, FXDIB_Argb, FXDIB_1bppCmyk, FXDIB_8bppCmyk,
+ FXDIB_Cmyk, FXDIB_8bppCmyka, FXDIB_Cmyka};
+
+} // namespace
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ constexpr size_t kParameterSize = 33;
+ if (size < kParameterSize)
+ return 0;
+
+ int width = GetInteger(data);
+ int height = GetInteger(data + 4);
+ uint32_t argb = GetInteger(data + 8);
+ int src_left = GetInteger(data + 12);
+ int src_top = GetInteger(data + 16);
+ int dest_left = GetInteger(data + 20);
+ int dest_top = GetInteger(data + 24);
+
+ BlendMode blend_mode = static_cast<BlendMode>(
+ data[28] % (static_cast<int>(BlendMode::kLast) + 1));
+ FXDIB_Format dest_format = kFormat[data[29] % FX_ArraySize(kFormat)];
+ FXDIB_Format src_format = kFormat[data[30] % FX_ArraySize(kFormat)];
+ bool is_clip = !(data[31] % 2);
+ bool is_rgb_byte_order = !(data[32] % 2);
+ size -= kParameterSize;
+ data += kParameterSize;
+
+ auto src_bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
+ auto dest_bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
+ if (!src_bitmap->Create(width, height, src_format) ||
+ !dest_bitmap->Create(width, height, dest_format)) {
+ return 0;
+ }
+ if (!src_bitmap->GetBuffer() || !dest_bitmap->GetBuffer()) {
+ return 0;
+ }
+
+ std::unique_ptr<CFX_ClipRgn> clip_rgn;
+ if (is_clip)
+ clip_rgn = pdfium::MakeUnique<CFX_ClipRgn>(width, height);
+ if (src_bitmap->IsAlphaMask()) {
+ dest_bitmap->CompositeMask(dest_left, dest_top, width, height, src_bitmap,
+ argb, src_left, src_top, blend_mode,
+ clip_rgn.get(), is_rgb_byte_order);
+ } else {
+ dest_bitmap->CompositeBitmap(dest_left, dest_top, width, height, src_bitmap,
+ src_left, src_top, blend_mode, clip_rgn.get(),
+ is_rgb_byte_order);
+ }
+ return 0;
+}