src/hb-aat-layout-common.hh | 2 +- src/hb-machinery.hh | 4 ++++ src/hb-null.hh | 17 +++++++++++++++-- src/hb-ot-kern-table.hh | 2 +- src/hb-ot-var-fvar-table.hh | 31 ++++++++++++++++--------------- 5 files changed, 37 insertions(+), 19 deletions(-)
New commits: commit 3b9fd176e83bbebc4d0b5fc967c15b08fdef7015 Author: Behdad Esfahbod <[email protected]> Date: Thu Nov 22 01:18:55 2018 -0500 Disallow taking Null() of unbounded structs Not sure I've marked all such structs. To be done as we discover. Fixes https://github.com/harfbuzz/harfbuzz/issues/1300 diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 6572b26d..7340996e 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -69,7 +69,7 @@ struct LookupFormat0 UnsizedArrayOf<T> arrayZ; /* Array of lookup values, indexed by glyph index. */ public: - DEFINE_SIZE_ARRAY (2, arrayZ); + DEFINE_SIZE_UNBOUNDED (2); }; diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index a8d1ad53..cb30e990 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -112,6 +112,10 @@ static inline Type& StructAfter(TObject &X) enum { null_size = (size) }; \ enum { min_size = (size) } +#define DEFINE_SIZE_UNBOUNDED(size) \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)) \ + enum { min_size = (size) } + #define DEFINE_SIZE_ARRAY(size, array) \ DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \ DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof ((array)[0])) \ diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 14e06568..ebb231a1 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -154,7 +154,7 @@ struct KernSubTable KernSubTableFormat3<KernSubTableHeader> format3; } u; public: - DEFINE_SIZE_MIN (0); + DEFINE_SIZE_UNBOUNDED (KernSubTableHeader::static_size); }; diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh index 5c8832e1..fed334e8 100644 --- a/src/hb-ot-var-fvar-table.hh +++ b/src/hb-ot-var-fvar-table.hh @@ -65,7 +65,7 @@ struct InstanceRecord // * instance. */ public: - DEFINE_SIZE_ARRAY (4, coordinatesZ); + DEFINE_SIZE_UNBOUNDED (4); }; struct AxisRecord @@ -109,7 +109,7 @@ struct fvar axisSize == 20 && /* Assumed in our code. */ instanceSize >= axisCount * 4 + 4 && get_axes ().sanitize (c) && - c->check_range (&get_instance (0), instanceCount, instanceSize)); + c->check_range (get_instance (0), instanceCount, instanceSize)); } inline unsigned int get_axis_count (void) const @@ -240,15 +240,17 @@ struct fvar inline hb_ot_name_id_t get_instance_subfamily_name_id (unsigned int instance_index) const { - const InstanceRecord &instance = get_instance (instance_index); - return instance.subfamilyNameID; + const InstanceRecord *instance = get_instance (instance_index); + if (unlikely (!instance)) return HB_OT_NAME_ID_INVALID; + return instance->subfamilyNameID; } inline hb_ot_name_id_t get_instance_postscript_name_id (unsigned int instance_index) const { - const InstanceRecord &instance = get_instance (instance_index); + const InstanceRecord *instance = get_instance (instance_index); + if (unlikely (!instance)) return HB_OT_NAME_ID_INVALID; if (instanceSize >= axisCount * 4 + 6) - return StructAfter<NameID> (instance.get_coordinates (axisCount)); + return StructAfter<NameID> (instance->get_coordinates (axisCount)); return HB_OT_NAME_ID_INVALID; } @@ -256,7 +258,8 @@ struct fvar unsigned int *coords_length, /* IN/OUT */ float *coords /* OUT */) const { - if (unlikely (instance_index >= instanceCount)) + const InstanceRecord *instance = get_instance (instance_index); + if (unlikely (!instance)) { if (coords_length) *coords_length = 0; @@ -265,9 +268,8 @@ struct fvar if (coords_length && *coords_length) { - const InstanceRecord &instance = get_instance (instance_index); - hb_array_t<const Fixed> instanceCoords = instance.get_coordinates (axisCount) - .sub_array (0, *coords_length); + hb_array_t<const Fixed> instanceCoords = instance->get_coordinates (axisCount) + .sub_array (0, *coords_length); for (unsigned int i = 0; i < instanceCoords.len; i++) coords[i] = instanceCoords.arrayZ[i].to_float (); } @@ -278,12 +280,11 @@ struct fvar inline hb_array_t<const AxisRecord> get_axes (void) const { return hb_array (&(this+firstAxis), axisCount); } - inline const InstanceRecord &get_instance (unsigned int i) const + inline const InstanceRecord *get_instance (unsigned int i) const { - if (unlikely (i >= instanceCount)) return Null (InstanceRecord); - - return StructAtOffset<InstanceRecord> (&StructAfter<InstanceRecord> (get_axes ()), - i * instanceSize); + if (unlikely (i >= instanceCount)) return nullptr; + return &StructAtOffset<InstanceRecord> (&StructAfter<InstanceRecord> (get_axes ()), + i * instanceSize); } protected: commit f2b91d6510face95008151bb0d25837723536f9f Author: Behdad Esfahbod <[email protected]> Date: Thu Nov 22 01:10:22 2018 -0500 Use Type::null_size for our structs in Null(), sizeof() for other types diff --git a/src/hb-null.hh b/src/hb-null.hh index 51f653d2..92c7a351 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -38,13 +38,26 @@ #define HB_NULL_POOL_SIZE 1024 +/* Use SFINAE to sniff whether T has min_size; in which case return T::null_size, + * otherwise return sizeof(T). */ +template <typename T, bool b> +struct _hb_null_size +{ enum { value = sizeof (T) }; }; +template <typename T> +struct _hb_null_size<T, T::min_size ? false : false> +{ enum { value = T::null_size }; }; + +template <typename T> +struct hb_null_size +{ enum { value = _hb_null_size<T, false>::value }; }; + extern HB_INTERNAL hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)]; /* Generic nul-content Null objects. */ template <typename Type> static inline Type const & Null (void) { - static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); + static_assert (hb_null_size<Type>::value <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); return *reinterpret_cast<Type const *> (_hb_NullPool); } #define Null(Type) Null<typename hb_remove_const<typename hb_remove_reference<Type>::value>::value>() @@ -85,7 +98,7 @@ extern HB_INTERNAL /* CRAP pool: Common Region for Access Protection. */ template <typename Type> static inline Type& Crap (void) { - static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); + static_assert (hb_null_size<Type>::value <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); Type *obj = reinterpret_cast<Type *> (_hb_CrapPool); memcpy (obj, &Null(Type), sizeof (*obj)); return *obj; _______________________________________________ HarfBuzz mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/harfbuzz
