1 #include "hb-fuzzer.hh"
8 #include "hb-subset-repacker.h"
18 /* The fuzzer seed contains a serialized representation of a object graph which forms
19 * the input graph to the repacker call. The binary format is:
22 * number of objects: 2 bytes
23 * objects[number of objects]:
25 * blob: blob size bytes
26 * num of real links: 2 bytes
27 * links[number of real links]: link_t struct
29 * TODO(garretrieger): add optional virtual links
33 bool read(const uint8_t** data, size_t* size, T* out)
35 if (*size < sizeof (T)) return false;
37 memcpy(out, *data, sizeof (T));
45 void cleanup (hb_object_t* objects, uint16_t num_objects)
47 for (uint32_t i = 0; i < num_objects; i++)
49 free (objects[i].head);
50 free (objects[i].real_links);
54 void add_links_to_objects (hb_object_t* objects, uint16_t num_objects,
55 link_t* links, uint16_t num_links)
57 unsigned* link_count = (unsigned*) calloc (num_objects, sizeof (unsigned));
59 for (uint32_t i = 0; i < num_links; i++)
61 uint16_t parent_idx = links[i].parent;
62 link_count[parent_idx]++;
65 for (uint32_t i = 0; i < num_objects; i++)
67 objects[i].num_real_links = link_count[i];
68 objects[i].real_links = (hb_link_t*) calloc (link_count[i], sizeof (hb_link_t));
69 objects[i].num_virtual_links = 0;
70 objects[i].virtual_links = nullptr;
73 for (uint32_t i = 0; i < num_links; i++)
75 uint16_t parent_idx = links[i].parent;
76 uint16_t child_idx = links[i].child + 1; // All indices are shifted by 1 by the null object.
77 hb_link_t* link = &(objects[parent_idx].real_links[link_count[parent_idx] - 1]);
79 link->width = links[i].width;
80 link->position = links[i].position;
81 link->objidx = child_idx;
82 link_count[parent_idx]--;
88 extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size)
90 // TODO(garretrieger): move graph validity checks into repacker graph creation.
91 alloc_state = _fuzzing_alloc_state (data, size);
93 uint16_t num_objects = 0;
94 hb_object_t* objects = nullptr;
96 uint16_t num_real_links = 0;
97 link_t* links = nullptr;
100 if (!read<hb_tag_t> (&data, &size, &table_tag)) goto end;
101 if (!read<uint16_t> (&data, &size, &num_objects)) goto end;
103 objects = (hb_object_t*) calloc (num_objects, sizeof (hb_object_t));
104 for (uint32_t i = 0; i < num_objects; i++)
107 if (!read<uint16_t> (&data, &size, &blob_size)) goto end;
108 if (size < blob_size) goto end;
110 char* copy = (char*) calloc (1, blob_size);
111 memcpy (copy, data, blob_size);
112 objects[i].head = (char*) copy;
113 objects[i].tail = (char*) (copy + blob_size);
119 if (!read<uint16_t> (&data, &size, &num_real_links)) goto end;
120 links = (link_t*) calloc (num_real_links, sizeof (link_t));
121 for (uint32_t i = 0; i < num_real_links; i++)
123 if (!read<link_t> (&data, &size, &links[i])) goto end;
125 if (links[i].parent >= num_objects)
129 add_links_to_objects (objects, num_objects,
130 links, num_real_links);
132 hb_blob_destroy (hb_subset_repack_or_fail (table_tag,
139 cleanup (objects, num_objects);