From 68b78914595347008eb344859699dc62257a7a67 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 7 Jul 2023 17:07:11 -0600 Subject: [PATCH] [sanitize] Add "fastpath" for ArrayOfOffset16To<> objects with max size Unfortunately this doesn't speed up NotoNastaliq or Gulzar as I was hoping for. Their GSUB tables are not large enough for this to kick in... --- src/OT/Layout/GSUB/Ligature.hh | 1 + src/hb-machinery.hh | 4 ++++ src/hb-null.hh | 9 +++++++++ src/hb-open-type.hh | 25 +++++++++++++++++++++++++ src/hb-ot-layout-gsubgpos.hh | 2 ++ 5 files changed, 41 insertions(+) diff --git a/src/OT/Layout/GSUB/Ligature.hh b/src/OT/Layout/GSUB/Ligature.hh index 402ed12ae..db3fc55f7 100644 --- a/src/OT/Layout/GSUB/Ligature.hh +++ b/src/OT/Layout/GSUB/Ligature.hh @@ -19,6 +19,7 @@ struct Ligature * in writing direction */ public: DEFINE_SIZE_ARRAY (Types::size + 2, component); + DEFINE_SIZE_MAX (65536 * Types::HBGlyphID::static_size); bool sanitize (hb_sanitize_context_t *c) const { diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index ecff94f1b..cde1e99d6 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -131,6 +131,10 @@ static inline Type& StructAfter(TObject &X) unsigned int get_size () const { return (size - (array).min_size + (array).get_size ()); } \ DEFINE_SIZE_ARRAY(size, array) +#define DEFINE_SIZE_MAX(size) \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) <= (size)) \ + static constexpr unsigned max_size = (size) + /* diff --git a/src/hb-null.hh b/src/hb-null.hh index 024089397..298251628 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -48,6 +48,15 @@ template using hb_has_min_size = _hb_has_min_size; #define hb_has_min_size(T) hb_has_min_size::value +template +struct _hb_has_max_size : hb_false_type {}; +template +struct _hb_has_max_size> + : hb_true_type {}; +template +using hb_has_max_size = _hb_has_max_size; +#define hb_has_max_size(T) hb_has_max_size::value + template struct _hb_has_null_size : hb_false_type {}; template diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index d41e44c99..3fbd6d362 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -312,6 +312,8 @@ struct _hb_has_null template struct OffsetTo : Offset { + using target_t = Type; + // Make sure Type is not unbounded; works only for types that are fully defined at OffsetTo time. static_assert (has_null == false || (hb_has_null_size (Type) || !hb_has_min_size (Type)), ""); @@ -712,6 +714,29 @@ struct ArrayOf return_trace (out); } + /* Special-case ArrayOf Offset16To structs with a maximum size. */ + template + bool sanitize (hb_sanitize_context_t *c, const Base *base) const + { + TRACE_SANITIZE (this); + + if (unlikely (!sanitize_shallow (c))) return_trace (false); + + unsigned max_len = 65536 + Type::target_t::max_size; + + if (unlikely (c->check_range_fast (base, max_len))) + return_trace (true); + + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + if (unlikely (!c->dispatch (arrayZ[i], base))) + return_trace (false); + return_trace (true); + } + template bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const { diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 1a9204d9f..ffe1c6aa8 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -2030,6 +2030,7 @@ struct Rule * design order */ public: DEFINE_SIZE_ARRAY (4, inputZ); + DEFINE_SIZE_MAX (65536 * (Types::HBUINT::static_size + LookupRecord::static_size)); }; template @@ -3111,6 +3112,7 @@ struct ChainRule * design order) */ public: DEFINE_SIZE_MIN (8); + DEFINE_SIZE_MAX (65536 * (3 * Types::HBUINT::static_size + LookupRecord::static_size)); }; template