/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 | } |