From bc4c5341d6e5725a6ad231eba3a7a6f2ba606ce9 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Thu, 23 Sep 2021 14:41:42 -0700 Subject: [PATCH] [repacker] Add test for virtual links in the repacker. --- src/hb-serialize.hh | 24 ++++++++++++++++++ src/test-repacker.cc | 60 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index f4c8fabc2..328c7b401 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -364,6 +364,30 @@ struct hb_serialize_context_t assert (packed.tail ()->head == tail); } + void add_link (VirtualOffset &ofs, objidx_t objidx) + { + // This link is not associated with an actual offset and exists merely to enforce + // an ordering constraint. + if (unlikely (in_error ())) return; + + if (!objidx) + return; + + assert (current); + assert (current->head <= (const char *) &ofs); + + auto& link = *current->links.push (); + if (current->links.in_error ()) + err (HB_SERIALIZE_ERROR_OTHER); + + link.width = 0; + link.objidx = objidx; + link.is_signed = 0; + link.whence = 0; + link.position = 0; + link.bias = 0; + } + template void add_link (T &ofs, objidx_t objidx, whence_t whence = Head, diff --git a/src/test-repacker.cc b/src/test-repacker.cc index aa4872535..66e5aa1e7 100644 --- a/src/test-repacker.cc +++ b/src/test-repacker.cc @@ -97,6 +97,13 @@ static void run_resolve_overflow_test (const char* name, free (out_buffer); } +static void add_virtual_offset (unsigned id, + hb_serialize_context_t* c) +{ + VirtualOffset* offset = c->start_embed (); + c->add_link (*offset, id); +} + static void populate_serializer_simple (hb_serialize_context_t* c) { @@ -748,6 +755,33 @@ populate_serializer_complex_3 (hb_serialize_context_t* c) c->end_serialize(); } +static void +populate_serializer_virtual_link (hb_serialize_context_t* c) +{ + c->start_serialize (); + + unsigned obj_d = add_object ("d", 1, c); + + start_object ("b", 1, c); + add_offset (obj_d, c); + unsigned obj_b = c->pop_pack (); + + start_object ("e", 1, c); + add_virtual_offset (obj_b, c); + unsigned obj_e = c->pop_pack(); + + start_object ("c", 1, c); + add_offset (obj_e, c); + unsigned obj_c = c->pop_pack (); + + start_object ("a", 1, c); + add_offset (obj_b, c); + add_offset (obj_c, c); + c->pop_pack (); + + c->end_serialize(); +} + static void test_sort_kahn_1 () { size_t buffer_size = 100; @@ -1186,7 +1220,32 @@ static void test_resolve_overflows_via_splitting_spaces_2 () 1); free (buffer); free (expected_buffer); +} +static void test_virtual_link () +{ + size_t buffer_size = 100; + void* buffer = malloc (buffer_size); + hb_serialize_context_t c (buffer, buffer_size); + populate_serializer_virtual_link (&c); + + void* out_buffer = malloc (buffer_size); + hb_serialize_context_t out (out_buffer, buffer_size); + + hb_resolve_overflows (c.object_graph (), HB_TAG_NONE, &out); + assert (!out.offset_overflow ()); + + hb_bytes_t result = out.copy_bytes (); + assert (result.length == 5 + 4 * 2); + assert (result[0] == 'a'); + assert (result[5] == 'c'); + assert (result[8] == 'e'); + assert (result[9] == 'b'); + assert (result[12] == 'd'); + + result.fini (); + free (buffer); + free (out_buffer); } // TODO(garretrieger): update will_overflow tests to check the overflows array. @@ -1214,4 +1273,5 @@ main (int argc, char **argv) test_resolve_overflows_via_splitting_spaces_2 (); test_duplicate_leaf (); test_duplicate_interior (); + test_virtual_link (); }