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