[repacker] get repacker fuzzer working.
Additionally add helper method that allows a graph to be saved as a fuzzer seed.
This commit is contained in:
parent
261a605f9c
commit
deca30b268
|
@ -953,6 +953,56 @@ struct graph_t
|
|||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Saves the current graph to a packed binary format which the repacker fuzzer takes
|
||||
* as a seed.
|
||||
*/
|
||||
void save_fuzzer_seed (hb_tag_t tag) const
|
||||
{
|
||||
FILE* f = fopen ("./repacker_fuzzer_seed", "w");
|
||||
fwrite ((void*) &tag, sizeof (tag), 1, f);
|
||||
|
||||
uint16_t num_objects = vertices_.length;
|
||||
fwrite ((void*) &num_objects, sizeof (num_objects), 1, f);
|
||||
|
||||
for (const auto& v : vertices_)
|
||||
{
|
||||
uint16_t blob_size = v.table_size ();
|
||||
fwrite ((void*) &blob_size, sizeof (blob_size), 1, f);
|
||||
fwrite ((const void*) v.obj.head, blob_size, 1, f);
|
||||
}
|
||||
|
||||
uint16_t link_count = 0;
|
||||
for (const auto& v : vertices_)
|
||||
link_count += v.obj.real_links.length;
|
||||
|
||||
fwrite ((void*) &link_count, sizeof (link_count), 1, f);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t parent;
|
||||
uint16_t child;
|
||||
uint16_t position;
|
||||
uint8_t width;
|
||||
} link_t;
|
||||
|
||||
for (unsigned i = 0; i < vertices_.length; i++)
|
||||
{
|
||||
for (const auto& l : vertices_[i].obj.real_links)
|
||||
{
|
||||
link_t link {
|
||||
(uint16_t) i, (uint16_t) l.objidx,
|
||||
(uint16_t) l.position, (uint8_t) l.width
|
||||
};
|
||||
fwrite ((void*) &link, sizeof (link), 1, f);
|
||||
}
|
||||
}
|
||||
|
||||
fclose (f);
|
||||
}
|
||||
#endif
|
||||
|
||||
void print_orphaned_nodes ()
|
||||
{
|
||||
if (!DEBUG_ENABLED(SUBSET_REPACK)) return;
|
||||
|
|
|
@ -378,7 +378,7 @@ hb_resolve_overflows (const T& packed,
|
|||
graph_t sorted_graph (packed);
|
||||
if (!sorted_graph.is_fully_connected ())
|
||||
{
|
||||
DEBUG_MSG (SUBSET_REPACK, nullptr, "Input graph is not fully connected.");
|
||||
sorted_graph.print_orphaned_nodes ();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,10 @@ bool read(const uint8_t** data, size_t* size, T* out)
|
|||
void cleanup (hb_object_t* objects, uint16_t num_objects)
|
||||
{
|
||||
for (uint32_t i = 0; i < num_objects; i++)
|
||||
{
|
||||
free (objects[i].head);
|
||||
free (objects[i].real_links);
|
||||
}
|
||||
}
|
||||
|
||||
void add_links_to_objects (hb_object_t* objects, uint16_t num_objects,
|
||||
|
@ -56,7 +59,7 @@ void add_links_to_objects (hb_object_t* objects, uint16_t num_objects,
|
|||
for (uint32_t i = 0; i < num_links; i++)
|
||||
{
|
||||
uint16_t parent_idx = links[i].parent;
|
||||
uint16_t child_idx = links[i].child;
|
||||
uint16_t child_idx = links[i].child + 1; // All indices are shifted by 1 by the null object.
|
||||
hb_link_t* link = &(objects[parent_idx].real_links[link_count[parent_idx] - 1]);
|
||||
|
||||
link->width = links[i].width;
|
||||
|
@ -89,8 +92,10 @@ extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size)
|
|||
if (!read<uint16_t> (&data, &size, &blob_size)) goto end;
|
||||
if (size < blob_size) goto end;
|
||||
|
||||
objects[i].head = (char*) data;
|
||||
objects[i].tail = (char*) (data + blob_size);
|
||||
char* copy = (char*) calloc (1, blob_size);
|
||||
memcpy (copy, data, blob_size);
|
||||
objects[i].head = (char*) copy;
|
||||
objects[i].tail = (char*) (copy + blob_size);
|
||||
|
||||
size -= blob_size;
|
||||
data += blob_size;
|
||||
|
@ -103,7 +108,7 @@ extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size)
|
|||
if (!read<link_t> (&data, &size, &links[i])) goto end;
|
||||
|
||||
if (links[i].parent >= num_objects
|
||||
|| links[i].child >= links[i].parent) // Enforces DAG graph
|
||||
|| links[i].child > links[i].parent) // Enforces DAG graph
|
||||
goto end;
|
||||
|
||||
if (links[i].width < 2 || links[i].width > 4) goto end;
|
||||
|
|
Loading…
Reference in New Issue