From 3b9fd176e83bbebc4d0b5fc967c15b08fdef7015 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 01:18:55 -0500 Subject: [PATCH] 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 --- src/hb-aat-layout-common.hh | 2 +- src/hb-machinery.hh | 4 ++++ src/hb-ot-kern-table.hh | 2 +- src/hb-ot-var-fvar-table.hh | 31 ++++++++++++++++--------------- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 6572b26d8..7340996e5 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -69,7 +69,7 @@ struct LookupFormat0 UnsizedArrayOf 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 a8d1ad53c..cb30e9907 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 14e065684..ebb231a10 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -154,7 +154,7 @@ struct KernSubTable KernSubTableFormat3 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 5c8832e18..fed334e8a 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 (instance.get_coordinates (axisCount)); + return StructAfter (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 instanceCoords = instance.get_coordinates (axisCount) - .sub_array (0, *coords_length); + hb_array_t 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 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 (&StructAfter (get_axes ()), - i * instanceSize); + if (unlikely (i >= instanceCount)) return nullptr; + return &StructAtOffset (&StructAfter (get_axes ()), + i * instanceSize); } protected: