/src/harfbuzz/test/fuzzing/hb-set-fuzzer.cc
Line | Count | Source (jump to first uncovered line) |
1 | | #include "hb-fuzzer.hh" |
2 | | |
3 | | #include <stdlib.h> |
4 | | #include <stdio.h> |
5 | | #include <string.h> |
6 | | #include <assert.h> |
7 | | |
8 | | #include "hb.h" |
9 | | |
10 | | // Only allow ~5,000 set values between the two input sets. |
11 | | // Arbitrarily long input sets do not trigger any meaningful |
12 | | // differences in behaviour so there's no benefit from allowing |
13 | | // the fuzzer to create super large sets. |
14 | 88 | #define MAX_INPUT_SIZE 20000 |
15 | | |
16 | | enum set_operation_t : uint8_t |
17 | | { |
18 | | INTERSECT = 0, |
19 | | UNION = 1, |
20 | | SUBTRACT = 2, |
21 | | SYMMETRIC_DIFFERENCE = 3 |
22 | | }; |
23 | | |
24 | | struct instructions_t |
25 | | { |
26 | | set_operation_t operation; |
27 | | uint32_t first_set_size; |
28 | | }; |
29 | | |
30 | | static hb_set_t *create_set (const uint32_t *value_array, int count) |
31 | 0 | { |
32 | 0 | hb_set_t *set = hb_set_create (); |
33 | 0 | for (int i = 0; i < count; i++) |
34 | 0 | hb_set_add (set, value_array[i]); |
35 | 0 | return set; |
36 | 0 | } |
37 | | |
38 | | |
39 | | extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size) |
40 | 104 | { |
41 | 104 | alloc_state = _fuzzing_alloc_state (data, size); |
42 | | |
43 | 104 | if (size < sizeof (instructions_t)) |
44 | 16 | return 0; |
45 | | |
46 | 88 | if (size > MAX_INPUT_SIZE) |
47 | 26 | return 0; |
48 | | |
49 | 62 | #pragma GCC diagnostic push |
50 | 62 | #pragma GCC diagnostic ignored "-Wstrict-aliasing" |
51 | 62 | const instructions_t &instructions = reinterpret_cast<const instructions_t &> (data); |
52 | 62 | #pragma GCC diagnostic pop |
53 | 62 | data += sizeof (instructions_t); |
54 | 62 | size -= sizeof (instructions_t); |
55 | | |
56 | 62 | const uint32_t *values = reinterpret_cast<const uint32_t *> (data); |
57 | 62 | size = size / sizeof (uint32_t); |
58 | | |
59 | 62 | if (size < instructions.first_set_size) |
60 | 62 | return 0; |
61 | | |
62 | 0 | hb_set_t *set_a = create_set (values, instructions.first_set_size); |
63 | |
|
64 | 0 | values += instructions.first_set_size; |
65 | 0 | size -= instructions.first_set_size; |
66 | 0 | hb_set_t *set_b = create_set (values, size); |
67 | |
|
68 | 0 | switch (instructions.operation) |
69 | 0 | { |
70 | 0 | case INTERSECT: |
71 | 0 | hb_set_intersect (set_a, set_b); |
72 | 0 | break; |
73 | 0 | case UNION: |
74 | 0 | hb_set_union (set_a, set_b); |
75 | 0 | break; |
76 | 0 | case SUBTRACT: |
77 | 0 | hb_set_subtract (set_a, set_b); |
78 | 0 | break; |
79 | 0 | case SYMMETRIC_DIFFERENCE: |
80 | 0 | hb_set_symmetric_difference (set_a, set_b); |
81 | 0 | break; |
82 | 0 | default: |
83 | 0 | break; |
84 | 0 | } |
85 | | |
86 | 0 | hb_set_destroy (set_a); |
87 | 0 | hb_set_destroy (set_b); |
88 | |
|
89 | 0 | return 0; |
90 | 0 | } |