Coverage Report

Created: 2026-03-31 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/leptonica/prog/fuzzing/pix_rotate_shear_fuzzer.cc
Line
Count
Source
1
// The fuzzer takes as input a buffer of bytes. The buffer is read in as:
2
// <angle>, <x_center>, <y_center>, and the remaining bytes will be read
3
// in as a <pix>. The image is then rotated by angle around the center. All
4
// inputs should not result in undefined behavior.
5
#include <cmath>
6
#include <cstddef>
7
#include <cstdint>
8
#include <cstdlib>
9
#include <cstring>
10
#include "leptfuzz.h"
11
12
// Set to true only for debugging; always false for production
13
static const bool DebugOutput = false;
14
15
namespace {
16
17
// Reads the front bytes of a data buffer containing `size` bytes as an int16_t,
18
// and advances the buffer forward [if there is sufficient capacity]. If there
19
// is insufficient capacity, this returns 0 and does not modify size or data.
20
18.3k
int16_t ReadInt16(const uint8_t** data, size_t* size) {
21
18.3k
  int16_t result = 0;
22
18.3k
  if (*size >= sizeof(result)) {
23
18.3k
    memcpy(&result, *data, sizeof(result));
24
18.3k
    *data += sizeof(result);
25
18.3k
    *size -= sizeof(result);
26
18.3k
  }
27
18.3k
  return result;
28
18.3k
}
29
30
}  // namespace
31
32
6.10k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
33
6.10k
  const int16_t angle = ReadInt16(&data, &size);
34
6.10k
  const int16_t x_center = ReadInt16(&data, &size);
35
6.10k
  const int16_t y_center = ReadInt16(&data, &size);
36
37
6.10k
  leptSetStdNullHandler();
38
39
  // Don't do pnm format (which can cause timeouts) or
40
  // jpeg format (which can have uninitialized variables).
41
  // tiff and png can also take too much memory in this test,
42
  // but not in applications because they abort quickly after
43
  // reading the header and computing the size of the data.
44
  // Note that the format checker requires at least 12 bytes.
45
6.10k
  if (size < 12) return EXIT_SUCCESS;
46
6.09k
  int format;
47
6.09k
  findFileFormatBuffer(data, &format);
48
6.09k
  if (format == IFF_PNM || format == IFF_JFIF_JPEG ||
49
6.08k
      format == IFF_TIFF || format == IFF_PNG) return EXIT_SUCCESS;
50
51
6.07k
  Pix* pix = pixReadMem(reinterpret_cast<const unsigned char*>(data), size);
52
6.07k
  if (pix == nullptr) {
53
4.82k
    return EXIT_SUCCESS;
54
4.82k
  }
55
56
  // Never in production
57
1.24k
  if (DebugOutput) {
58
0
    L_INFO("w = %d, h = %d, d = %d\n", "fuzzer",
59
0
           pixGetWidth(pix), pixGetHeight(pix), pixGetDepth(pix));
60
0
  }
61
62
1.24k
  constexpr float deg2rad = M_PI / 180.;
63
1.24k
  Pix* pix_rotated = pixRotateShear(pix, x_center, y_center, deg2rad * angle,
64
1.24k
                                    L_BRING_IN_WHITE);
65
1.24k
  if (pix_rotated) {
66
820
    pixDestroy(&pix_rotated);
67
820
  }
68
69
1.24k
  pixDestroy(&pix);
70
  return EXIT_SUCCESS;
71
6.07k
}