diff --git a/src/hb-array.hh b/src/hb-array.hh index 09d10b47c..d9adf2c72 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -196,6 +196,15 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> const T *as () const { return length < hb_null_size (T) ? &Null (T) : reinterpret_cast (arrayZ); } + template + bool in_range (const T *p, unsigned int size = T::static_size) const + { + return ((const char *) p) >= arrayZ + && ((const char *) p + size) <= arrayZ + length; + } + /* Only call if you allocated the underlying array using malloc() or similar. */ void free () { ::free ((void *) arrayZ); arrayZ = nullptr; length = 0; } diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index 44f84ec71..571e50ea0 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -360,9 +360,9 @@ struct glyf { typedef const CompositeGlyphChain *__item_t__; composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) : - glyph (glyph_), current (current_), checker (range_checker_t (glyph.arrayZ, glyph.length)) + glyph (glyph_), current (current_) { if (!in_range (current)) current = nullptr; } - composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr), checker (range_checker_t (nullptr, 0)) {} + composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr) {} const CompositeGlyphChain &__item__ () const { return *current; } bool __more__ () const { return current; } @@ -380,14 +380,13 @@ struct glyf bool in_range (const CompositeGlyphChain *composite) const { - return checker.in_range (composite, CompositeGlyphChain::min_size) - && checker.in_range (composite, composite->get_size ()); + return glyph.in_range (composite, CompositeGlyphChain::min_size) + && glyph.in_range (composite, composite->get_size ()); } private: hb_bytes_t glyph; __item_t__ current; - range_checker_t checker; }; struct Glyph @@ -537,7 +536,7 @@ struct glyf template static bool read_points (const HBUINT8 *&p /* IN/OUT */, contour_point_vector_t &points_ /* IN/OUT */, - const range_checker_t &checker) + const hb_bytes_t &bytes) { T coord_setter; float v = 0; @@ -546,7 +545,7 @@ struct glyf uint8_t flag = points_[i].flag; if (coord_setter.is_short (flag)) { - if (unlikely (!checker.in_range (p))) return false; + if (unlikely (!bytes.in_range (p))) return false; if (coord_setter.is_same (flag)) v += *p++; else @@ -556,7 +555,7 @@ struct glyf { if (!coord_setter.is_same (flag)) { - if (unlikely (!checker.in_range ((const HBUINT16 *) p))) return false; + if (unlikely (!bytes.in_range ((const HBUINT16 *) p))) return false; v += *(const HBINT16 *) p; p += HBINT16::static_size; } @@ -571,9 +570,8 @@ struct glyf const bool phantom_only=false) const { const HBUINT16 *endPtsOfContours = &StructAfter (header); - range_checker_t checker (bytes.arrayZ, bytes.length); int num_contours = header.numberOfContours; - if (unlikely (!checker.in_range (&endPtsOfContours[num_contours + 1]))) return false; + if (unlikely (!bytes.in_range (&endPtsOfContours[num_contours + 1]))) return false; unsigned int num_points = endPtsOfContours[num_contours - 1] + 1; points_.resize (num_points + PHANTOM_COUNT); @@ -593,12 +591,12 @@ struct glyf /* Read flags */ for (unsigned int i = 0; i < num_points; i++) { - if (unlikely (!checker.in_range (p))) return false; + if (unlikely (!bytes.in_range (p))) return false; uint8_t flag = *p++; points_[i].flag = flag; if (flag & FLAG_REPEAT) { - if (unlikely (!checker.in_range (p))) return false; + if (unlikely (!bytes.in_range (p))) return false; unsigned int repeat_count = *p++; while ((repeat_count-- > 0) && (++i < num_points)) points_[i].flag = flag; @@ -606,8 +604,8 @@ struct glyf } /* Read x & y coordinates */ - return (read_points (p, points_, checker) && - read_points (p, points_, checker)); + return (read_points (p, points_, bytes) && + read_points (p, points_, bytes)); } }; @@ -949,7 +947,7 @@ struct glyf bool get_extents_var (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const - { return get_var_extents_and_phantoms (font, gid, extents); } + { return get_var_extents_and_phantoms (font, gid, extents); } #endif public: diff --git a/src/hb-ot-var-gvar-table.hh b/src/hb-ot-var-gvar-table.hh index 666b30895..a76121d86 100644 --- a/src/hb-ot-var-gvar-table.hh +++ b/src/hb-ot-var-gvar-table.hh @@ -78,23 +78,6 @@ struct contour_point_vector_t : hb_vector_t } }; -struct range_checker_t -{ - range_checker_t (const void *data_, unsigned int length_) - : data ((const char *) data_), length (length_) {} - - template - bool in_range (const T *p, unsigned int size = T::static_size) const - { - return ((const char *) p) >= data - && ((const char *) p + size) <= data + length; - } - - protected: - const char *data; - const unsigned int length; -}; - struct Tuple : UnsizedArrayOf {}; struct TuppleIndex : HBUINT16 @@ -233,10 +216,10 @@ struct GlyphVarData { if (var_data->has_shared_point_numbers ()) { - range_checker_t checker (var_data, length); + hb_bytes_t bytes ((const char *) var_data, length); const HBUINT8 *base = &(var_data+var_data->data); const HBUINT8 *p = base; - if (!unpack_points (p, shared_indices, checker)) return false; + if (!unpack_points (p, shared_indices, bytes)) return false; data_offset = p - base; } return true; @@ -292,7 +275,7 @@ struct GlyphVarData static bool unpack_points (const HBUINT8 *&p /* IN/OUT */, hb_vector_t &points /* OUT */, - const range_checker_t &check) + const hb_bytes_t &bytes) { enum packed_point_flag_t { @@ -300,12 +283,12 @@ struct GlyphVarData POINT_RUN_COUNT_MASK = 0x7F }; - if (unlikely (!check.in_range (p))) return false; + if (unlikely (!bytes.in_range (p))) return false; uint16_t count = *p++; if (count & POINTS_ARE_WORDS) { - if (unlikely (!check.in_range (p))) return false; + if (unlikely (!bytes.in_range (p))) return false; count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++; } points.resize (count); @@ -314,7 +297,7 @@ struct GlyphVarData uint16_t i = 0; while (i < count) { - if (unlikely (!check.in_range (p))) return false; + if (unlikely (!bytes.in_range (p))) return false; uint16_t j; uint8_t control = *p++; uint16_t run_count = (control & POINT_RUN_COUNT_MASK) + 1; @@ -322,7 +305,7 @@ struct GlyphVarData { for (j = 0; j < run_count && i < count; j++, i++) { - if (unlikely (!check.in_range ((const HBUINT16 *) p))) + if (unlikely (!bytes.in_range ((const HBUINT16 *) p))) return false; n += *(const HBUINT16 *)p; points[i] = n; @@ -333,7 +316,7 @@ struct GlyphVarData { for (j = 0; j < run_count && i < count; j++, i++) { - if (unlikely (!check.in_range (p))) return false; + if (unlikely (!bytes.in_range (p))) return false; n += *p++; points[i] = n; } @@ -345,7 +328,7 @@ struct GlyphVarData static bool unpack_deltas (const HBUINT8 *&p /* IN/OUT */, hb_vector_t &deltas /* IN/OUT */, - const range_checker_t &check) + const hb_bytes_t &bytes) { enum packed_delta_flag_t { @@ -358,7 +341,7 @@ struct GlyphVarData unsigned int count = deltas.length; while (i < count) { - if (unlikely (!check.in_range (p))) return false; + if (unlikely (!bytes.in_range (p))) return false; uint8_t control = *p++; unsigned int run_count = (control & DELTA_RUN_COUNT_MASK) + 1; unsigned int j; @@ -368,7 +351,7 @@ struct GlyphVarData else if (control & DELTAS_ARE_WORDS) for (j = 0; j < run_count && i < count; j++, i++) { - if (unlikely (!check.in_range ((const HBUINT16 *) p))) + if (unlikely (!bytes.in_range ((const HBUINT16 *) p))) return false; deltas[i] = *(const HBINT16 *) p; p += HBUINT16::static_size; @@ -376,7 +359,7 @@ struct GlyphVarData else for (j = 0; j < run_count && i < count; j++, i++) { - if (unlikely (!check.in_range (p))) + if (unlikely (!bytes.in_range (p))) return false; deltas[i] = *(const HBINT8 *) p++; } @@ -611,10 +594,10 @@ struct gvar if (unlikely (!iterator.in_range (p, length))) return false; - range_checker_t checker (p, length); + hb_bytes_t bytes ((const char *) p, length); hb_vector_t private_indices; if (iterator.current_tuple->has_private_points () && - !GlyphVarData::unpack_points (p, private_indices, checker)) + !GlyphVarData::unpack_points (p, private_indices, bytes)) return false; const hb_array_t &indices = private_indices.length ? private_indices : shared_indices; @@ -622,11 +605,11 @@ struct gvar unsigned int num_deltas = apply_to_all ? points.length : indices.length; hb_vector_t x_deltas; x_deltas.resize (num_deltas); - if (!GlyphVarData::unpack_deltas (p, x_deltas, checker)) + if (!GlyphVarData::unpack_deltas (p, x_deltas, bytes)) return false; hb_vector_t y_deltas; y_deltas.resize (num_deltas); - if (!GlyphVarData::unpack_deltas (p, y_deltas, checker)) + if (!GlyphVarData::unpack_deltas (p, y_deltas, bytes)) return false; for (unsigned int i = 0; i < deltas.length; i++)