[repacker] Validate link positions before running the repacker.

This commit is contained in:
Garret Rieger 2022-09-08 22:59:34 +00:00
parent 88d437525f
commit edf7a29595
4 changed files with 37 additions and 0 deletions

View File

@ -49,6 +49,34 @@ struct graph_t
unsigned end = 0; unsigned end = 0;
unsigned priority = 0; unsigned priority = 0;
bool link_positions_valid (unsigned parent_index)
{
hb_set_t assigned_bytes;
for (const auto& l : obj.real_links)
{
unsigned start = l.position;
unsigned end = start + l.width - 1;
if (unlikely (end >= table_size ()))
{
DEBUG_MSG (SUBSET_REPACK, nullptr,
"Invalid graph. Link position is out of bounds.");
return false;
}
if (unlikely (assigned_bytes.intersects (start, end)))
{
DEBUG_MSG (SUBSET_REPACK, nullptr,
"Invalid graph. Found offsets whose positions overlap.");
return false;
}
assigned_bytes.add_range (start, end);
}
return true;
}
void normalize () void normalize ()
{ {
obj.real_links.qsort (); obj.real_links.qsort ();
@ -299,6 +327,8 @@ struct graph_t
vertex_t* v = vertices_.push (); vertex_t* v = vertices_.push ();
if (check_success (!vertices_.in_error ())) if (check_success (!vertices_.in_error ()))
v->obj = *objects[i]; v->obj = *objects[i];
check_success (v->link_positions_valid (i));
if (!removed_nil) continue; if (!removed_nil) continue;
// Fix indices to account for removed nil object. // Fix indices to account for removed nil object.
for (auto& l : v->obj.all_links_writer ()) { for (auto& l : v->obj.all_links_writer ()) {

View File

@ -376,6 +376,12 @@ hb_resolve_overflows (const T& packed,
unsigned max_rounds = 20, unsigned max_rounds = 20,
bool recalculate_extensions = false) { bool recalculate_extensions = false) {
graph_t sorted_graph (packed); graph_t sorted_graph (packed);
if (sorted_graph.in_error ())
{
// Invalid graph definition.
return nullptr;
}
if (!sorted_graph.is_fully_connected ()) if (!sorted_graph.is_fully_connected ())
{ {
sorted_graph.print_orphaned_nodes (); sorted_graph.print_orphaned_nodes ();

View File

@ -73,6 +73,7 @@ void add_links_to_objects (hb_object_t* objects, uint16_t num_objects,
extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size) extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size)
{ {
// TODO(garretrieger): move graph validity checks into repacker graph creation.
alloc_state = _fuzzing_alloc_state (data, size); alloc_state = _fuzzing_alloc_state (data, size);
uint16_t num_objects = 0; uint16_t num_objects = 0;