[serialize] Allow offset links that have base offset from the object base
authorBehdad Esfahbod <behdad@behdad.org>
Tue, 2 Apr 2019 23:53:05 +0000 (16:53 -0700)
committerBehdad Esfahbod <behdad@behdad.org>
Tue, 2 Apr 2019 23:53:42 +0000 (16:53 -0700)
Rarely used, but used, in name table or similar constructs.

src/hb-serialize.hh

index a0b9228..9b7143e 100644 (file)
@@ -68,6 +68,7 @@ struct hb_serialize_context_t
     {
       bool is_wide: 1;
       unsigned position : 31;
+      int bias;
       objidx_t objidx;
     };
 
@@ -228,19 +229,18 @@ struct hb_serialize_context_t
       return;
 
     assert (current.length);
-    unsigned i = current.length - 1;
+    assert (current.tail ().head <= (const char *) &ofs);
+
     if (!base)
-      base = current[i].head;
+      base = current.tail ().head;
     else
-    {
-      while (i && base < current[i].head)
-        i--;
-      assert (base == current[i].head);
-    }
+      assert (current.tail ().head <= (const char *) base);
 
-    auto& link = *current[i].links.push ();
+    /* FUCK.  Check ofs lies within current object? */
+    auto& link = *current.tail ().links.push ();
     link.is_wide = sizeof (T) == 4;
     link.position = (const char *) &ofs - (const char *) base;
+    link.bias = (const char *) base - current.tail ().head;
     link.objidx = objidx;
   }
 
@@ -256,7 +256,7 @@ struct hb_serialize_context_t
       {
         const object_t::link_t &link = *link_it;
        const object_t &child = packed[link.objidx];
-       unsigned offset = child.head - parent.head;
+       unsigned offset = (child.head - parent.head) - link.bias;
 
        if (link.is_wide)
        {