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
This commit is contained in:
Behdad Esfahbod 2018-11-22 01:18:55 -05:00
parent f2b91d6510
commit 3b9fd176e8
4 changed files with 22 additions and 17 deletions

View File

@ -69,7 +69,7 @@ struct LookupFormat0
UnsizedArrayOf<T> UnsizedArrayOf<T>
arrayZ; /* Array of lookup values, indexed by glyph index. */ arrayZ; /* Array of lookup values, indexed by glyph index. */
public: public:
DEFINE_SIZE_ARRAY (2, arrayZ); DEFINE_SIZE_UNBOUNDED (2);
}; };

View File

@ -112,6 +112,10 @@ static inline Type& StructAfter(TObject &X)
enum { null_size = (size) }; \ enum { null_size = (size) }; \
enum { min_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 DEFINE_SIZE_ARRAY(size, array) \
DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \ DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \
DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof ((array)[0])) \ DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof ((array)[0])) \

View File

@ -154,7 +154,7 @@ struct KernSubTable
KernSubTableFormat3<KernSubTableHeader> format3; KernSubTableFormat3<KernSubTableHeader> format3;
} u; } u;
public: public:
DEFINE_SIZE_MIN (0); DEFINE_SIZE_UNBOUNDED (KernSubTableHeader::static_size);
}; };

View File

@ -65,7 +65,7 @@ struct InstanceRecord
// * instance. */ // * instance. */
public: public:
DEFINE_SIZE_ARRAY (4, coordinatesZ); DEFINE_SIZE_UNBOUNDED (4);
}; };
struct AxisRecord struct AxisRecord
@ -109,7 +109,7 @@ struct fvar
axisSize == 20 && /* Assumed in our code. */ axisSize == 20 && /* Assumed in our code. */
instanceSize >= axisCount * 4 + 4 && instanceSize >= axisCount * 4 + 4 &&
get_axes ().sanitize (c) && 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 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 inline hb_ot_name_id_t get_instance_subfamily_name_id (unsigned int instance_index) const
{ {
const InstanceRecord &instance = get_instance (instance_index); const InstanceRecord *instance = get_instance (instance_index);
return instance.subfamilyNameID; 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 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) 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; return HB_OT_NAME_ID_INVALID;
} }
@ -256,7 +258,8 @@ struct fvar
unsigned int *coords_length, /* IN/OUT */ unsigned int *coords_length, /* IN/OUT */
float *coords /* OUT */) const float *coords /* OUT */) const
{ {
if (unlikely (instance_index >= instanceCount)) const InstanceRecord *instance = get_instance (instance_index);
if (unlikely (!instance))
{ {
if (coords_length) if (coords_length)
*coords_length = 0; *coords_length = 0;
@ -265,9 +268,8 @@ struct fvar
if (coords_length && *coords_length) if (coords_length && *coords_length)
{ {
const InstanceRecord &instance = get_instance (instance_index); hb_array_t<const Fixed> instanceCoords = instance->get_coordinates (axisCount)
hb_array_t<const Fixed> instanceCoords = instance.get_coordinates (axisCount) .sub_array (0, *coords_length);
.sub_array (0, *coords_length);
for (unsigned int i = 0; i < instanceCoords.len; i++) for (unsigned int i = 0; i < instanceCoords.len; i++)
coords[i] = instanceCoords.arrayZ[i].to_float (); coords[i] = instanceCoords.arrayZ[i].to_float ();
} }
@ -278,12 +280,11 @@ struct fvar
inline hb_array_t<const AxisRecord> get_axes (void) const inline hb_array_t<const AxisRecord> get_axes (void) const
{ return hb_array (&(this+firstAxis), axisCount); } { 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); if (unlikely (i >= instanceCount)) return nullptr;
return &StructAtOffset<InstanceRecord> (&StructAfter<InstanceRecord> (get_axes ()),
return StructAtOffset<InstanceRecord> (&StructAfter<InstanceRecord> (get_axes ()), i * instanceSize);
i * instanceSize);
} }
protected: protected: