• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Arbitarily 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 #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 
create_set(const uint32_t * value_array,int count)30 static hb_set_t *create_set (const uint32_t *value_array, int count)
31 {
32   hb_set_t *set = hb_set_create ();
33   for (int i = 0; i < count; i++)
34     hb_set_add (set, value_array[i]);
35   return set;
36 }
37 
38 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)39 extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size)
40 {
41   alloc_state = size; /* see src/failing-alloc.c */
42 
43   if (size < sizeof (instructions_t))
44     return 0;
45 
46   if (size > MAX_INPUT_SIZE)
47     return 0;
48 
49 #pragma GCC diagnostic push
50 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
51   const instructions_t &instructions = reinterpret_cast<const instructions_t &> (data);
52 #pragma GCC diagnostic pop
53   data += sizeof (instructions_t);
54   size -= sizeof (instructions_t);
55 
56   const uint32_t *values = reinterpret_cast<const uint32_t *> (data);
57   size = size / sizeof (uint32_t);
58 
59   if (size < instructions.first_set_size)
60     return 0;
61 
62   hb_set_t *set_a = create_set (values, instructions.first_set_size);
63 
64   values += instructions.first_set_size;
65   size -= instructions.first_set_size;
66   hb_set_t *set_b = create_set (values, size);
67 
68   switch (instructions.operation)
69   {
70   case INTERSECT:
71     hb_set_intersect (set_a, set_b);
72     break;
73   case UNION:
74     hb_set_union (set_a, set_b);
75     break;
76   case SUBTRACT:
77     hb_set_subtract (set_a, set_b);
78     break;
79   case SYMMETRIC_DIFFERENCE:
80     hb_set_symmetric_difference (set_a, set_b);
81     break;
82   default:
83     break;
84   }
85 
86   hb_set_destroy (set_a);
87   hb_set_destroy (set_b);
88 
89   return 0;
90 }
91