Coverage Report

Created: 2026-06-13 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/harfbuzz/test/fuzzing/hb-fuzzer.hh
Line
Count
Source
1
#include <hb-config.hh>
2
3
#include <hb.h>
4
#include <stddef.h>
5
#include <string.h>
6
7
extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size);
8
9
#if defined(__GNUC__) && (__GNUC__ >= 4) || (__clang__)
10
#define HB_UNUSED __attribute__((unused))
11
#else
12
#define HB_UNUSED
13
#endif
14
15
#ifdef HB_IS_IN_FUZZER
16
17
/* See src/failing-alloc.c */
18
extern "C" int alloc_state;
19
20
#else
21
22
/* Just a dummy global variable */
23
static int HB_UNUSED alloc_state = 0;
24
25
#endif
26
27
static inline int
28
_fuzzing_alloc_state (const uint8_t *data, size_t size)
29
37.0k
{
30
  /* https://github.com/harfbuzz/harfbuzz/pull/2764#issuecomment-1172589849 */
31
32
  /* In 50% of the runs, don't fail the allocator. */
33
37.0k
  if (size && data[size - 1] < 0x80)
34
29.9k
    return 0;
35
36
7.15k
  return size;
37
37.0k
}
38
39
static const uint8_t _fuzzing_extended_magic[] = {'H', 'B', 'S', 'U', 'B', 'F', 'Z', '2'};
40
41
enum _fuzzing_extended_op_t
42
{
43
  HB_FUZZING_OP_SET_FLAGS = 1,
44
  HB_FUZZING_OP_KEEP_EVERYTHING = 2,
45
  HB_FUZZING_OP_SET_CLEAR = 3,
46
  HB_FUZZING_OP_SET_INVERT = 4,
47
  HB_FUZZING_OP_SET_ADD_RANGES = 5,
48
  HB_FUZZING_OP_SET_DEL_RANGES = 6,
49
  HB_FUZZING_OP_TEXT_ADD = 7,
50
  HB_FUZZING_OP_TEXT_DEL = 8,
51
  HB_FUZZING_OP_AXIS_PIN_ALL_TO_DEFAULT = 9,
52
  HB_FUZZING_OP_AXIS_SET = 10,
53
};
54
55
enum _fuzzing_extended_axis_mode_t
56
{
57
  HB_FUZZING_AXIS_PIN_TO_DEFAULT = 0,
58
  HB_FUZZING_AXIS_SET_RANGE = 1,
59
};
60
61
static inline uint32_t
62
_fuzzing_read_u32_le (const uint8_t *p)
63
14.6k
{
64
14.6k
  return (uint32_t) p[0] |
65
14.6k
         ((uint32_t) p[1] << 8) |
66
14.6k
         ((uint32_t) p[2] << 16) |
67
14.6k
         ((uint32_t) p[3] << 24);
68
14.6k
}
69
70
static inline float
71
_fuzzing_read_f32_le (const uint8_t *p)
72
8.20k
{
73
8.20k
  uint32_t bits = _fuzzing_read_u32_le (p);
74
8.20k
  float value;
75
8.20k
  memcpy (&value, &bits, sizeof (value));
76
8.20k
  return value;
77
8.20k
}
78
79
template <typename T>
80
static inline bool
81
_fuzzing_read_value (const uint8_t *&p,
82
                     const uint8_t *end,
83
                     T *out)
84
21.5k
{
85
21.5k
  if ((size_t) (end - p) < sizeof (T))
86
5
    return false;
87
88
21.5k
  memcpy (out, p, sizeof (T));
89
21.5k
  p += sizeof (T);
90
21.5k
  return true;
91
21.5k
}
92
93
static inline bool
94
_fuzzing_read_u32_value (const uint8_t *&p,
95
                         const uint8_t *end,
96
                         uint32_t *out)
97
6.19k
{
98
6.19k
  if ((size_t) (end - p) < 4)
99
74
    return false;
100
6.12k
  *out = _fuzzing_read_u32_le (p);
101
6.12k
  p += 4;
102
6.12k
  return true;
103
6.19k
}
104
105
static inline bool
106
_fuzzing_read_f32_value (const uint8_t *&p,
107
                         const uint8_t *end,
108
                         float *out)
109
8.23k
{
110
8.23k
  if ((size_t) (end - p) < 4)
111
28
    return false;
112
8.20k
  *out = _fuzzing_read_f32_le (p);
113
8.20k
  p += 4;
114
8.20k
  return true;
115
8.23k
}