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; +}