src/hb-open-file.hh | 30 ++++++++------------- src/hb-open-type.hh | 58 ++++++++++++++++++++++++++++++++++++----- src/hb-ot-layout-gsub-table.hh | 10 +++---- src/hb-ot-layout-gsubgpos.hh | 10 +++---- 4 files changed, 73 insertions(+), 35 deletions(-)
New commits: commit 3789c557ca06aef430726f4942cafecac6fe4eef Author: Behdad Esfahbod <[email protected]> Date: Thu Sep 13 20:30:04 2018 +0200 [dfont] Solve the mystery +2 offset thing! Previously, ResourceForkHeader was defined as 30 bytes, having the typeCountM1 as last member. There was a mysterious offset-by-2 in the code, derived from FontTools and JDK code this was ported from. In testing, I observed that typeListZ offset is actually 28. Suggesting that the typeCountM1 does NOT actually belong to ResourceForkHeader, but belongs to the array itself. Adjusting for that resolves the mystery +2 offset hack, so everything is clean and good now. This, concludes my dfont hacking. The code looks great now, and I'm happy to leave it. Fuzzers might disagree though, we will see! diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index 5c653fed..cd7d78a3 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -357,13 +357,6 @@ struct ResourceTypeRecord struct ResourceMap { - inline const ResourceTypeRecord& get_type_record (unsigned int i) const - { - // Why offset from the third byte of the object? I'm not sure - return hb_array_t<ResourceTypeRecord> (((2 + (const char *) this )+typeListZ).arrayZ, - get_type_count ()) [i]; - } - inline unsigned int get_face_count (void) const { unsigned int count = get_type_count (); @@ -386,7 +379,7 @@ struct ResourceMap /* The check for idx < count is here because ResourceRecord is NOT null-safe. * Because an offset of 0 there does NOT mean null. */ if (type.is_sfnt () && idx < type.get_resource_count ()) - return type.get_resource_record (idx, &(this+typeListZ)).get_face (data_base); + return type.get_resource_record (idx, &(this+typeList)).get_face (data_base); } return Null (OpenTypeFontFace); } @@ -394,30 +387,31 @@ struct ResourceMap inline bool sanitize (hb_sanitize_context_t *c, const void *data_base) const { TRACE_SANITIZE (this); - const void *type_base = &(this+typeListZ); + const void *type_base = &(this+typeList); return_trace (c->check_struct (this) && - typeListZ.sanitize (c, 2 + (const char *) this, - get_type_count (), - type_base, - data_base)); + typeList.sanitize (c, this, + type_base, + data_base)); } private: - inline unsigned int get_type_count (void) const { return typeCountM1 + 1; } + inline unsigned int get_type_count (void) const { return (this+typeList).lenM1 + 1; } + + inline const ResourceTypeRecord& get_type_record (unsigned int i) const + { return (this+typeList)[i]; } protected: HBUINT8 reserved0[16]; /* Reserved for copy of resource header */ HBUINT32 reserved1; /* Reserved for handle to next resource map */ HBUINT16 resreved2; /* Reserved for file reference number */ HBUINT16 attrs; /* Resource fork attribute */ - OffsetTo<UnsizedArrayOf<ResourceTypeRecord> > - typeListZ; /* Offset from beginning of map to + OffsetTo<ArrayOfM1<ResourceTypeRecord> > + typeList; /* Offset from beginning of map to * resource type list */ Offset16 nameList; /* Offset from beginning of map to * resource name list */ - HBUINT16 typeCountM1; /* Number of types in the map minus 1 */ public: - DEFINE_SIZE_STATIC (30); + DEFINE_SIZE_STATIC (28); }; struct ResourceForkHeader diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 68079738..4f16c7d3 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -628,6 +628,50 @@ struct HeadlessArrayOf DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ); }; +/* An array storing length-1. */ +template <typename Type, typename LenType=HBUINT16> +struct ArrayOfM1 +{ + inline const Type& operator [] (unsigned int i) const + { + if (unlikely (i > lenM1)) return Null(Type); + return arrayZ[i]; + } + inline Type& operator [] (unsigned int i) + { + if (unlikely (i > lenM1)) return Crap(Type); + return arrayZ[i]; + } + inline unsigned int get_size (void) const + { return lenM1.static_size + (lenM1 + 1) * Type::static_size; } + + template <typename T> + inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const + { + TRACE_SANITIZE (this); + if (unlikely (!sanitize_shallow (c))) return_trace (false); + unsigned int count = lenM1 + 1; + for (unsigned int i = 0; i < count; i++) + if (unlikely (!arrayZ[i].sanitize (c, base, user_data))) + return_trace (false); + return_trace (true); + } + + private: + inline bool sanitize_shallow (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (lenM1.sanitize (c) && + (c->check_array (arrayZ, lenM1 + 1))); + } + + public: + LenType lenM1; + Type arrayZ[VAR]; + public: + DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ); +}; + /* An array with sorted elements. Supports binary searching. */ template <typename Type, typename LenType=HBUINT16> struct SortedArrayOf : ArrayOf<Type, LenType> commit effc7ced72a6ce0fea328a8b68dc3d55f09774f1 Author: Behdad Esfahbod <[email protected]> Date: Thu Sep 13 20:21:54 2018 +0200 Rename HeadlessArrayOf::len to lenP1 So it doesn't accidentally match our templates, etc. diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index b10d33b1..68079738 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -570,16 +570,16 @@ struct HeadlessArrayOf { inline const Type& operator [] (unsigned int i) const { - if (unlikely (i >= len || !i)) return Null(Type); + if (unlikely (i >= lenP1 || !i)) return Null(Type); return arrayZ[i-1]; } inline Type& operator [] (unsigned int i) { - if (unlikely (i >= len || !i)) return Crap(Type); + if (unlikely (i >= lenP1 || !i)) return Crap(Type); return arrayZ[i-1]; } inline unsigned int get_size (void) const - { return len.static_size + (len ? len - 1 : 0) * Type::static_size; } + { return lenP1.static_size + (lenP1 ? lenP1 - 1 : 0) * Type::static_size; } inline bool serialize (hb_serialize_context_t *c, Supplier<Type> &items, @@ -587,7 +587,7 @@ struct HeadlessArrayOf { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); - len.set (items_len); /* TODO(serialize) Overflow? */ + lenP1.set (items_len); /* TODO(serialize) Overflow? */ if (unlikely (!items_len)) return_trace (true); if (unlikely (!c->extend (*this))) return_trace (false); for (unsigned int i = 0; i < items_len - 1; i++) @@ -617,12 +617,12 @@ struct HeadlessArrayOf inline bool sanitize_shallow (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (len.sanitize (c) && - (!len || c->check_array (arrayZ, len - 1))); + return_trace (lenP1.sanitize (c) && + (!lenP1 || c->check_array (arrayZ, lenP1 - 1))); } public: - LenType len; + LenType lenP1; Type arrayZ[VAR]; public: DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ); diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 4d5db6ae..7e36e063 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -710,7 +710,7 @@ struct Ligature { inline bool intersects (const hb_set_t *glyphs) const { - unsigned int count = component.len; + unsigned int count = component.lenP1; for (unsigned int i = 1; i < count; i++) if (!glyphs->has (component[i])) return false; @@ -720,7 +720,7 @@ struct Ligature inline void closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); - unsigned int count = component.len; + unsigned int count = component.lenP1; for (unsigned int i = 1; i < count; i++) if (!c->glyphs->has (component[i])) return; @@ -730,14 +730,14 @@ struct Ligature inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - c->input->add_array (component.arrayZ, component.len ? component.len - 1 : 0); + c->input->add_array (component.arrayZ, component.lenP1 ? component.lenP1 - 1 : 0); c->output->add (ligGlyph); } inline bool would_apply (hb_would_apply_context_t *c) const { TRACE_WOULD_APPLY (this); - if (c->len != component.len) + if (c->len != component.lenP1) return_trace (false); for (unsigned int i = 1; i < c->len; i++) @@ -750,7 +750,7 @@ struct Ligature inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); - unsigned int count = component.len; + unsigned int count = component.lenP1; if (unlikely (!count)) return_trace (false); diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index eae73ce3..ff9783ed 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -1879,7 +1879,7 @@ struct ChainRule const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); return chain_context_intersects (glyphs, backtrack.len, backtrack.arrayZ, - input.len, input.arrayZ, + input.lenP1, input.arrayZ, lookahead.len, lookahead.arrayZ, lookup_context); } @@ -1892,7 +1892,7 @@ struct ChainRule const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); chain_context_closure_lookup (c, backtrack.len, backtrack.arrayZ, - input.len, input.arrayZ, + input.lenP1, input.arrayZ, lookahead.len, lookahead.arrayZ, lookup.len, lookup.arrayZ, lookup_context); @@ -1906,7 +1906,7 @@ struct ChainRule const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); chain_context_collect_glyphs_lookup (c, backtrack.len, backtrack.arrayZ, - input.len, input.arrayZ, + input.lenP1, input.arrayZ, lookahead.len, lookahead.arrayZ, lookup.len, lookup.arrayZ, lookup_context); @@ -1920,7 +1920,7 @@ struct ChainRule const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); return_trace (chain_context_would_apply_lookup (c, backtrack.len, backtrack.arrayZ, - input.len, input.arrayZ, + input.lenP1, input.arrayZ, lookahead.len, lookahead.arrayZ, lookup.len, lookup.arrayZ, lookup_context)); } @@ -1933,7 +1933,7 @@ struct ChainRule const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); return_trace (chain_context_apply_lookup (c, backtrack.len, backtrack.arrayZ, - input.len, input.arrayZ, + input.lenP1, input.arrayZ, lookahead.len, lookahead.arrayZ, lookup.len, lookup.arrayZ, lookup_context)); } _______________________________________________ HarfBuzz mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/harfbuzz
