From 4c3af7d406359d2addd51b2fc91d49b3a8d45c29 Mon Sep 17 00:00:00 2001 From: blueshade7 Date: Thu, 5 Mar 2020 15:40:44 -0800 Subject: [PATCH] add "add_link()" with bias arg issue #2227 --- src/hb-ot-cff-common.hh | 2 +- src/hb-serialize.hh | 37 +++++++++++++++++++++---------------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/hb-ot-cff-common.hh b/src/hb-ot-cff-common.hh index 809a29fc8..ccbc12ac3 100644 --- a/src/hb-ot-cff-common.hh +++ b/src/hb-ot-cff-common.hh @@ -415,7 +415,7 @@ struct Dict : UnsizedByteStr { T &ofs = *(T *) (c->head + OpCode_Size (int_op)); if (unlikely (!serialize_int_op (c, op, 0, int_op))) return false; - c->add_link (ofs, link, nullptr, whence); + c->add_link (ofs, link, whence); return true; } diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 21e8bcc23..628f5c833 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -278,8 +278,8 @@ struct hb_serialize_context_t template void add_link (T &ofs, objidx_t objidx, - const void *base = nullptr, - whence_t whence = Head) + whence_t whence, + unsigned bias = 0) { static_assert (sizeof (T) == 2 || sizeof (T) == 4, ""); @@ -293,23 +293,18 @@ struct hb_serialize_context_t link.is_wide = sizeof (T) == 4; link.is_signed = hb_is_signed (hb_unwrap_type (T)); - link.whence = (unsigned)whence; + link.whence = (unsigned) whence; link.position = (const char *) &ofs - current->head; - if (whence == Head) - { - if (base == nullptr) - link.bias = 0; - else - { - assert (current->head <= (const char *)base); - link.bias = (const char *) base - current->head; - } - } - else - link.bias = 0; + link.bias = bias; link.objidx = objidx; } + template + void add_link (T &ofs, objidx_t objidx, + const void *base = nullptr, + whence_t whence = Head) + { add_link (ofs, objidx, whence, to_bias (base)); } + void resolve_links () { if (unlikely (in_error ())) return; @@ -324,12 +319,14 @@ struct hb_serialize_context_t if (unlikely (!child)) { err_other_error(); return; } unsigned offset; switch ((whence_t)link.whence) { - case Head: offset = (child->head - parent->head) - link.bias; break; + case Head: offset = child->head - parent->head; break; case Tail: offset = child->head - parent->tail; break; case Absolute: offset = (head - start) + (child->head - tail); break; default: assert (0); } + assert (offset >= link.bias); + offset -= link.bias; if (link.is_signed) { if (link.is_wide) @@ -492,6 +489,14 @@ struct hb_serialize_context_t check_assign (off, offset); } + unsigned to_bias (const void *base) const + { + if (!base) return 0; + assert (current); + assert (current->head <= (const char *) base); + return (const char *) base - current->head; + } + public: /* TODO Make private. */ char *start, *head, *tail, *end; unsigned int debug_depth;