Coverage Report

Created: 2026-05-30 06:04

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
14.8k
{
30
  /* https://github.com/harfbuzz/harfbuzz/pull/2764#issuecomment-1172589849 */
31
32
  /* In 50% of the runs, don't fail the allocator. */
33
14.8k
  if (size && data[size - 1] < 0x80)
34
11.6k
    return 0;
35
36
3.17k
  return size;
37
14.8k
}
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
71.9k
{
64
71.9k
  return (uint32_t) p[0] |
65
71.9k
         ((uint32_t) p[1] << 8) |
66
71.9k
         ((uint32_t) p[2] << 16) |
67
71.9k
         ((uint32_t) p[3] << 24);
68
71.9k
}
69
70
static inline float
71
_fuzzing_read_f32_le (const uint8_t *p)
72
25.0k
{
73
25.0k
  uint32_t bits = _fuzzing_read_u32_le (p);
74
25.0k
  float value;
75
25.0k
  memcpy (&value, &bits, sizeof (value));
76
25.0k
  return value;
77
25.0k
}
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
12.6k
{
85
12.6k
  if ((size_t) (end - p) < sizeof (T))
86
12
    return false;
87
88
12.6k
  memcpy (out, p, sizeof (T));
89
12.6k
  p += sizeof (T);
90
12.6k
  return true;
91
12.6k
}
92
93
static inline bool
94
_fuzzing_read_u32_value (const uint8_t *&p,
95
                         const uint8_t *end,
96
                         uint32_t *out)
97
46.4k
{
98
46.4k
  if ((size_t) (end - p) < 4)
99
187
    return false;
100
46.3k
  *out = _fuzzing_read_u32_le (p);
101
46.3k
  p += 4;
102
46.3k
  return true;
103
46.4k
}
104
105
static inline bool
106
_fuzzing_read_f32_value (const uint8_t *&p,
107
                         const uint8_t *end,
108
                         float *out)
109
25.0k
{
110
25.0k
  if ((size_t) (end - p) < 4)
111
60
    return false;
112
25.0k
  *out = _fuzzing_read_f32_le (p);
113
25.0k
  p += 4;
114
25.0k
  return true;
115
25.0k
}