xref: /aosp_15_r20/external/pdfium/testing/fuzzers/pdf_scanlinecompositor_fuzzer.cc (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2019 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <iterator>
6 #include <memory>
7 
8 #include "core/fxcrt/fx_safe_types.h"
9 #include "core/fxge/cfx_cliprgn.h"
10 #include "core/fxge/dib/cfx_dibitmap.h"
11 #include "core/fxge/dib/fx_dib.h"
12 #include "testing/fuzzers/pdfium_fuzzer_util.h"
13 
14 namespace {
15 
16 // Some unused formats were removed, and their slots have been filled in
17 // `FXDIB_Format::kInvalid` to keep the fuzzer input stable.
18 constexpr FXDIB_Format kFormat[] = {
19     FXDIB_Format::kInvalid,
20     FXDIB_Format::k1bppRgb,
21     FXDIB_Format::k8bppRgb,
22     FXDIB_Format::kRgb,
23     FXDIB_Format::kRgb32,
24     FXDIB_Format::k1bppMask,
25     FXDIB_Format::k8bppMask,
26     FXDIB_Format::kInvalid /* Was FXDIB_Format::k8bppRgba */,
27     FXDIB_Format::kInvalid /* Was FXDIB_Format::kRgba */,
28     FXDIB_Format::kArgb,
29     FXDIB_Format::kInvalid /* Was FXDIB_Format::k1bppCmyk */,
30     FXDIB_Format::kInvalid /* Was FXDIB_Format::k8bppCmyk */,
31     FXDIB_Format::kInvalid /* Was FXDIB_Format::kCmyk */,
32     FXDIB_Format::kInvalid /* Was FXDIB_Format::k8bppCmyka */,
33     FXDIB_Format::kInvalid /* Was FXDIB_Format::kCmyka */};
34 
35 }  // namespace
36 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)37 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
38   constexpr size_t kParameterSize = 33;
39   if (size < kParameterSize)
40     return 0;
41 
42   int width = GetInteger(data);
43   int height = GetInteger(data + 4);
44   uint32_t argb = GetInteger(data + 8);
45   int src_left = GetInteger(data + 12);
46   int src_top = GetInteger(data + 16);
47   int dest_left = GetInteger(data + 20);
48   int dest_top = GetInteger(data + 24);
49 
50   BlendMode blend_mode = static_cast<BlendMode>(
51       data[28] % (static_cast<int>(BlendMode::kLast) + 1));
52   FXDIB_Format dest_format = kFormat[data[29] % std::size(kFormat)];
53   FXDIB_Format src_format = kFormat[data[30] % std::size(kFormat)];
54   bool is_clip = !(data[31] % 2);
55   bool is_rgb_byte_order = !(data[32] % 2);
56   size -= kParameterSize;
57   data += kParameterSize;
58 
59   static constexpr uint32_t kMemLimit = 512000000;  // 512 MB
60   static constexpr uint32_t kComponents = 4;
61   FX_SAFE_UINT32 mem = width;
62   mem *= height;
63   mem *= kComponents;
64   if (!mem.IsValid() || mem.ValueOrDie() > kMemLimit)
65     return 0;
66 
67   auto src_bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
68   auto dest_bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
69   if (!src_bitmap->Create(width, height, src_format) ||
70       !dest_bitmap->Create(width, height, dest_format)) {
71     return 0;
72   }
73   if (src_bitmap->GetBuffer().empty() || dest_bitmap->GetBuffer().empty()) {
74     return 0;
75   }
76 
77   std::unique_ptr<CFX_ClipRgn> clip_rgn;
78   if (is_clip)
79     clip_rgn = std::make_unique<CFX_ClipRgn>(width, height);
80   if (src_bitmap->IsMaskFormat()) {
81     dest_bitmap->CompositeMask(dest_left, dest_top, width, height, src_bitmap,
82                                argb, src_left, src_top, blend_mode,
83                                clip_rgn.get(), is_rgb_byte_order);
84   } else {
85     dest_bitmap->CompositeBitmap(dest_left, dest_top, width, height, src_bitmap,
86                                  src_left, src_top, blend_mode, clip_rgn.get(),
87                                  is_rgb_byte_order);
88   }
89   return 0;
90 }
91