Disallow null-enabled offsets to unsized structures...
...like UnsizedArrayOf<>. This fixes a class of crasher bugs, mostly with color and AAT tables. We cannot use nullable offsets to varsized data that does not declare min_size, because it's nost safe to use our fixed-size null pool for types that have their size external. So, use non_null'able offsets for these. A further enhancement would be to make use of min_size in Null<> itself. Will try that after.
This commit is contained in:
parent
9ff76c6025
commit
10642b3fbf
@ -243,7 +243,7 @@ struct LookupSegmentArray
|
||||
|
||||
GlyphID last; /* Last GlyphID in this segment */
|
||||
GlyphID first; /* First GlyphID in this segment */
|
||||
OffsetTo<UnsizedArrayOf<T> >
|
||||
OffsetTo<UnsizedArrayOf<T>, HBUINT16, false>
|
||||
valuesZ; /* A 16-bit offset from the start of
|
||||
* the table to the data. */
|
||||
public:
|
||||
@ -522,11 +522,11 @@ struct StateTable
|
||||
protected:
|
||||
HBUINT32 nClasses; /* Number of classes, which is the number of indices
|
||||
* in a single line in the state array. */
|
||||
LOffsetTo<Lookup<HBUINT16> >
|
||||
LOffsetTo<Lookup<HBUINT16>, false>
|
||||
classTable; /* Offset to the class table. */
|
||||
LOffsetTo<UnsizedArrayOf<HBUINT16> >
|
||||
LOffsetTo<UnsizedArrayOf<HBUINT16>, false>
|
||||
stateArrayTable;/* Offset to the state array. */
|
||||
LOffsetTo<UnsizedArrayOf<Entry<Extra> > >
|
||||
LOffsetTo<UnsizedArrayOf<Entry<Extra> >, false>
|
||||
entryTable; /* Offset to the entry array. */
|
||||
|
||||
public:
|
||||
|
@ -78,7 +78,7 @@ struct FeatureName
|
||||
protected:
|
||||
HBUINT16 feature; /* Feature type. */
|
||||
HBUINT16 nSettings; /* The number of records in the setting name array. */
|
||||
LOffsetTo<UnsizedArrayOf<SettingName> >
|
||||
LOffsetTo<UnsizedArrayOf<SettingName>, false>
|
||||
settingTable; /* Offset in bytes from the beginning of this table to
|
||||
* this feature's setting name array. The actual type of
|
||||
* record this offset refers to will depend on the
|
||||
|
@ -311,7 +311,7 @@ struct ContextualSubtable
|
||||
protected:
|
||||
StateTable<EntryData>
|
||||
machine;
|
||||
LOffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32> >
|
||||
LOffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32>, false>
|
||||
substitutionTables;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (20);
|
||||
@ -473,11 +473,11 @@ struct LigatureSubtable
|
||||
protected:
|
||||
StateTable<EntryData>
|
||||
machine;
|
||||
LOffsetTo<UnsizedArrayOf<HBUINT32> >
|
||||
LOffsetTo<UnsizedArrayOf<HBUINT32>, false>
|
||||
ligAction; /* Offset to the ligature action table. */
|
||||
LOffsetTo<UnsizedArrayOf<HBUINT16> >
|
||||
LOffsetTo<UnsizedArrayOf<HBUINT16>, false>
|
||||
component; /* Offset to the component table. */
|
||||
LOffsetTo<UnsizedArrayOf<GlyphID> >
|
||||
LOffsetTo<UnsizedArrayOf<GlyphID>, false>
|
||||
ligature; /* Offset to the actual ligature lists. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (28);
|
||||
@ -715,7 +715,7 @@ struct InsertionSubtable
|
||||
protected:
|
||||
StateTable<EntryData>
|
||||
machine;
|
||||
LOffsetTo<UnsizedArrayOf<GlyphID> >
|
||||
LOffsetTo<UnsizedArrayOf<GlyphID>, false>
|
||||
insertionAction; /* Byte offset from stateHeader to the start of
|
||||
* the insertion glyph table. */
|
||||
public:
|
||||
|
@ -68,7 +68,7 @@ struct TrackTableEntry
|
||||
protected:
|
||||
Fixed track; /* Track value for this record. */
|
||||
NameID trackNameID; /* The 'name' table index for this track */
|
||||
OffsetTo<UnsizedArrayOf<FWORD> >
|
||||
OffsetTo<UnsizedArrayOf<FWORD>, HBUINT16, false>
|
||||
valuesZ; /* Offset from start of tracking table to
|
||||
* per-size tracking values for this track. */
|
||||
|
||||
@ -134,7 +134,7 @@ struct TrackData
|
||||
protected:
|
||||
HBUINT16 nTracks; /* Number of separate tracks included in this table. */
|
||||
HBUINT16 nSizes; /* Number of point sizes included in this table. */
|
||||
LOffsetTo<UnsizedArrayOf<Fixed> >
|
||||
LOffsetTo<UnsizedArrayOf<Fixed>, false>
|
||||
sizeTable; /* Offset to array[nSizes] of size values. */
|
||||
UnsizedArrayOf<TrackTableEntry>
|
||||
trackTable; /* Array[nTracks] of TrackTableEntry records. */
|
||||
|
@ -46,7 +46,7 @@ struct FTStringRange
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetTo<UnsizedArrayOf<HBUINT8> >
|
||||
OffsetTo<UnsizedArrayOf<HBUINT8>, HBUINT16, false>
|
||||
tag; /* Offset from the start of the table to
|
||||
* the beginning of the string */
|
||||
HBUINT16 length; /* String length (in bytes) */
|
||||
|
@ -226,9 +226,14 @@ struct FixedVersion
|
||||
* Use: (base+offset)
|
||||
*/
|
||||
|
||||
template <typename Type, bool has_null_> struct assert_has_min_size { static_assert (Type::min_size > 0); };
|
||||
template <typename Type> struct assert_has_min_size<Type, false> {};
|
||||
|
||||
template <typename Type, typename OffsetType=HBUINT16, bool has_null=true>
|
||||
struct OffsetTo : Offset<OffsetType, has_null>
|
||||
{
|
||||
static_assert (sizeof (assert_has_min_size<Type, has_null>) || true);
|
||||
|
||||
inline const Type& operator () (const void *base) const
|
||||
{
|
||||
if (unlikely (this->is_null ())) return Null(Type);
|
||||
|
@ -264,8 +264,6 @@ struct IndexSubtableArray
|
||||
|
||||
protected:
|
||||
UnsizedArrayOf<IndexSubtableRecord> indexSubtablesZ;
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY(0, indexSubtablesZ);
|
||||
};
|
||||
|
||||
struct BitmapSizeTable
|
||||
@ -289,7 +287,7 @@ struct BitmapSizeTable
|
||||
}
|
||||
|
||||
protected:
|
||||
LOffsetTo<IndexSubtableArray>
|
||||
LOffsetTo<IndexSubtableArray, false>
|
||||
indexSubtableArrayOffset;
|
||||
HBUINT32 indexTablesSize;
|
||||
HBUINT32 numberOfIndexSubtables;
|
||||
|
@ -129,9 +129,9 @@ struct COLR
|
||||
protected:
|
||||
HBUINT16 version; /* Table version number */
|
||||
HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records */
|
||||
LOffsetTo<UnsizedArrayOf<BaseGlyphRecord> >
|
||||
LOffsetTo<UnsizedArrayOf<BaseGlyphRecord>, false>
|
||||
baseGlyphsZ; /* Offset to Base Glyph records. */
|
||||
LOffsetTo<UnsizedArrayOf<LayerRecord> >
|
||||
LOffsetTo<UnsizedArrayOf<LayerRecord>, false>
|
||||
layersZ; /* Offset to Layer Records */
|
||||
HBUINT16 numLayers; /* Number of Layer Records */
|
||||
public:
|
||||
|
@ -118,15 +118,15 @@ struct CPALV1Tail
|
||||
}
|
||||
|
||||
protected:
|
||||
LOffsetTo<UnsizedArrayOf<HBUINT32> >
|
||||
LOffsetTo<UnsizedArrayOf<HBUINT32>, false>
|
||||
paletteFlagsZ; /* Offset from the beginning of CPAL table to
|
||||
* the Palette Type Array. Set to 0 if no array
|
||||
* is provided. */
|
||||
LOffsetTo<UnsizedArrayOf<HBUINT16> >
|
||||
LOffsetTo<UnsizedArrayOf<HBUINT16>, false>
|
||||
paletteLabelZ; /* Offset from the beginning of CPAL table to
|
||||
* the Palette Labels Array. Set to 0 if no
|
||||
* array is provided. */
|
||||
LOffsetTo<UnsizedArrayOf<HBUINT16> >
|
||||
LOffsetTo<UnsizedArrayOf<HBUINT16>, false>
|
||||
paletteEntryLabelZ; /* Offset from the beginning of CPAL table to
|
||||
* the Palette Entry Label Array. Set to 0
|
||||
* if no array is provided. */
|
||||
@ -207,7 +207,7 @@ struct CPAL
|
||||
HBUINT16 numPalettes; /* Number of palettes in the table. */
|
||||
HBUINT16 numColorRecords; /* Total number of color records, combined for
|
||||
* all palettes. */
|
||||
LOffsetTo<UnsizedArrayOf<BGRAColor> >
|
||||
LOffsetTo<UnsizedArrayOf<BGRAColor>, false>
|
||||
colorRecordsZ; /* Offset from the beginning of CPAL table to
|
||||
* the first ColorRecord. */
|
||||
UnsizedArrayOf<HBUINT16>
|
||||
|
@ -54,7 +54,7 @@ struct SVGDocumentIndexEntry
|
||||
* this index entry. */
|
||||
HBUINT16 endGlyphID; /* The last glyph ID in the range described by
|
||||
* this index entry. Must be >= startGlyphID. */
|
||||
LOffsetTo<UnsizedArrayOf<HBUINT8> >
|
||||
LOffsetTo<UnsizedArrayOf<HBUINT8>, false>
|
||||
svgDoc; /* Offset from the beginning of the SVG Document Index
|
||||
* to an SVG document. Must be non-zero. */
|
||||
HBUINT32 svgDocLength; /* Length of the SVG document.
|
||||
|
@ -70,6 +70,11 @@ namespace OT {
|
||||
* Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList
|
||||
*/
|
||||
|
||||
struct Record_sanitize_closure_t {
|
||||
hb_tag_t tag;
|
||||
const void *list_base;
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct Record
|
||||
{
|
||||
@ -77,14 +82,10 @@ struct Record
|
||||
return tag.cmp (a);
|
||||
}
|
||||
|
||||
struct sanitize_closure_t {
|
||||
hb_tag_t tag;
|
||||
const void *list_base;
|
||||
};
|
||||
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
const sanitize_closure_t closure = {tag, base};
|
||||
const Record_sanitize_closure_t closure = {tag, base};
|
||||
return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure));
|
||||
}
|
||||
|
||||
@ -240,7 +241,7 @@ struct LangSys
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c,
|
||||
const Record<LangSys>::sanitize_closure_t * = nullptr) const
|
||||
const Record_sanitize_closure_t * = nullptr) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) && featureIndex.sanitize (c));
|
||||
@ -291,7 +292,7 @@ struct Script
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c,
|
||||
const Record<Script>::sanitize_closure_t * = nullptr) const
|
||||
const Record_sanitize_closure_t * = nullptr) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this));
|
||||
@ -526,6 +527,7 @@ struct FeatureParams
|
||||
FeatureParamsStylisticSet stylisticSet;
|
||||
FeatureParamsCharacterVariants characterVariants;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (17);
|
||||
};
|
||||
|
||||
@ -553,7 +555,7 @@ struct Feature
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c,
|
||||
const Record<Feature>::sanitize_closure_t *closure = nullptr) const
|
||||
const Record_sanitize_closure_t *closure = nullptr) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c))))
|
||||
|
@ -124,7 +124,7 @@ struct JstfPriority
|
||||
struct JstfLangSys : OffsetListOf<JstfPriority>
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c,
|
||||
const Record<JstfLangSys>::sanitize_closure_t * = nullptr) const
|
||||
const Record_sanitize_closure_t * = nullptr) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (OffsetListOf<JstfPriority>::sanitize (c));
|
||||
@ -165,7 +165,7 @@ struct JstfScript
|
||||
inline const JstfLangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c,
|
||||
const Record<JstfScript>::sanitize_closure_t * = nullptr) const
|
||||
const Record_sanitize_closure_t * = nullptr) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (extenderGlyphs.sanitize (c, this) &&
|
||||
|
Loading…
Reference in New Issue
Block a user