[HB] More sanitize()
This commit is contained in:
parent
70de50c11e
commit
cd3827ee56
@ -85,7 +85,7 @@ struct TTCHeader
|
||||
{
|
||||
friend struct OpenTypeFontFile;
|
||||
|
||||
STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION (TTCHeader, 2);
|
||||
STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION (TTCHeader, 1, 2);
|
||||
|
||||
private:
|
||||
Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
|
||||
|
@ -60,6 +60,7 @@ struct _hb_sanitize_context_t
|
||||
|
||||
#define SANITIZE_THIS(X) HB_LIKELY ((X).sanitize (SANITIZE_ARG, (const char *) this))
|
||||
#define SANITIZE_THIS2(X,Y) SANITIZE_THIS (X) && SANITIZE_THIS (Y)
|
||||
#define SANITIZE_THIS3(X,Y,Z) SANITIZE_THIS (X) && SANITIZE_THIS (Y) && SANITIZE_THIS(Z)
|
||||
|
||||
#define SANITIZE_SELF() SANITIZE_OBJ (*this)
|
||||
#define SANITIZE_OBJ(X) SANITIZE_MEM(&(X), sizeof (X))
|
||||
@ -205,12 +206,12 @@ struct Null <Type> \
|
||||
return *(const Type*)data; \
|
||||
}
|
||||
/* Like get_for_data(), but checks major version first. */
|
||||
#define STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION(Type, Major) \
|
||||
#define STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION(Type, MajorMin, MajorMax) \
|
||||
static inline const Type& get_for_data (const char *data) \
|
||||
{ \
|
||||
if (HB_UNLIKELY (data == NULL)) return Null(Type); \
|
||||
const Type& t = *(const Type*)data; \
|
||||
if (HB_UNLIKELY (!t.version.major || t.version.major > Major)) return Null(Type); \
|
||||
if (HB_UNLIKELY (t.version.major < MajorMin || t.version.major > MajorMax)) return Null(Type); \
|
||||
return t; \
|
||||
}
|
||||
|
||||
@ -348,6 +349,10 @@ struct FixedVersion
|
||||
{
|
||||
inline operator uint32_t (void) const { return (major << 16) + minor; }
|
||||
|
||||
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||
return SANITIZE_SELF ();
|
||||
}
|
||||
|
||||
USHORT major;
|
||||
USHORT minor;
|
||||
};
|
||||
@ -371,12 +376,11 @@ struct ArrayOf
|
||||
|
||||
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||
if (!(SANITIZE (len) && SANITIZE_GET_SIZE())) return false;
|
||||
/* For non-offset types, this shouldn't be needed
|
||||
/* XXX For non-recursive types, this is too much overhead */
|
||||
unsigned int count = len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (!SANITIZE (array[i]))
|
||||
return false;
|
||||
*/
|
||||
}
|
||||
|
||||
USHORT len;
|
||||
|
@ -46,6 +46,12 @@
|
||||
template <typename Type>
|
||||
struct Record
|
||||
{
|
||||
inline bool sanitize (SANITIZE_ARG_DEF, const char *base) {
|
||||
/* Note: Doesn't sanitize referenced object */
|
||||
/* Only accept ASCII-visible tags (mind DEL) */
|
||||
return (tag & 0x80808080) == 0 && offset.sanitize (SANITIZE_ARG, base);
|
||||
}
|
||||
|
||||
Tag tag; /* 4-byte Tag identifier */
|
||||
OffsetTo<Type>
|
||||
offset; /* Offset from beginning of object holding
|
||||
@ -53,7 +59,19 @@ struct Record
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct RecordListOf : ArrayOf<Record<Type> >
|
||||
struct RecordArrayOf : ArrayOf<Record<Type> >
|
||||
{
|
||||
inline bool sanitize (SANITIZE_ARG_DEF, const char *base) {
|
||||
if (!(SANITIZE (this->len) && SANITIZE_GET_SIZE())) return false;
|
||||
unsigned int count = this->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (!SANITIZE_THIS (this->array[i]))
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct RecordListOf : RecordArrayOf<Type>
|
||||
{
|
||||
inline const Type& operator [] (unsigned int i) const
|
||||
{
|
||||
@ -65,18 +83,16 @@ struct RecordListOf : ArrayOf<Record<Type> >
|
||||
if (HB_UNLIKELY (i >= this->len)) return Null(Tag);
|
||||
return this->array[i].tag;
|
||||
}
|
||||
|
||||
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||
return RecordArrayOf<Type>::sanitize (SANITIZE_ARG, (const char *) this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Script;
|
||||
typedef Record<Script> ScriptRecord;
|
||||
ASSERT_SIZE (ScriptRecord, 6);
|
||||
struct LangSys;
|
||||
typedef Record<LangSys> LangSysRecord;
|
||||
ASSERT_SIZE (LangSysRecord, 6);
|
||||
struct Feature;
|
||||
typedef Record<Feature> FeatureRecord;
|
||||
ASSERT_SIZE (FeatureRecord, 6);
|
||||
|
||||
|
||||
struct LangSys
|
||||
@ -92,6 +108,10 @@ struct LangSys
|
||||
return reqFeatureIndex;;
|
||||
}
|
||||
|
||||
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||
return SANITIZE_SELF () && SANITIZE (featureIndex);
|
||||
}
|
||||
|
||||
Offset lookupOrder; /* = Null (reserved for an offset to a
|
||||
* reordering table) */
|
||||
USHORT reqFeatureIndex;/* Index of a feature required for this
|
||||
@ -119,11 +139,15 @@ struct Script
|
||||
inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; }
|
||||
inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
|
||||
|
||||
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||
return SANITIZE_THIS (defaultLangSys) && SANITIZE_THIS (langSys);
|
||||
}
|
||||
|
||||
private:
|
||||
OffsetTo<LangSys>
|
||||
defaultLangSys; /* Offset to DefaultLangSys table--from
|
||||
* beginning of Script table--may be Null */
|
||||
ArrayOf<LangSysRecord>
|
||||
RecordArrayOf<LangSys>
|
||||
langSys; /* Array of LangSysRecords--listed
|
||||
* alphabetically by LangSysTag */
|
||||
};
|
||||
@ -138,6 +162,10 @@ struct Feature
|
||||
inline const unsigned int get_lookup_index (unsigned int i) const { return lookupIndex[i]; }
|
||||
inline unsigned int get_lookup_count (void) const { return lookupIndex.len; }
|
||||
|
||||
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||
return SANITIZE_SELF () && SANITIZE (lookupIndex);
|
||||
}
|
||||
|
||||
/* TODO: implement get_feature_parameters() */
|
||||
/* TODO: implement FeatureSize and other special features? */
|
||||
Offset featureParams; /* Offset to Feature Parameters table (if one
|
||||
@ -169,6 +197,10 @@ ASSERT_SIZE (LookupFlag, 2);
|
||||
|
||||
struct LookupSubTable
|
||||
{
|
||||
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||
return SANITIZE_SELF ();
|
||||
}
|
||||
|
||||
private:
|
||||
USHORT format; /* Subtable format. Different for GSUB and GPOS */
|
||||
};
|
||||
@ -192,6 +224,16 @@ struct Lookup
|
||||
return flag;
|
||||
}
|
||||
|
||||
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||
if (!(SANITIZE_SELF () && SANITIZE_THIS (subTable))) return false;
|
||||
if (HB_UNLIKELY (lookupFlag & LookupFlag::UseMarkFilteringSet))
|
||||
{
|
||||
USHORT &markFilteringSet = *(USHORT*) ((char *) &subTable + subTable.get_size ());
|
||||
if (!SANITIZE (markFilteringSet)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
USHORT lookupType; /* Different enumerations for GSUB and GPOS */
|
||||
USHORT lookupFlag; /* Lookup qualifiers */
|
||||
OffsetArrayOf<LookupSubTable>
|
||||
@ -210,6 +252,10 @@ struct OffsetListOf : OffsetArrayOf<Type>
|
||||
if (HB_UNLIKELY (i >= this->len)) return Null(Type);
|
||||
return this+this->array[i];
|
||||
}
|
||||
|
||||
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||
return OffsetArrayOf<Type>::sanitize (SANITIZE_ARG, (const char *) this);
|
||||
}
|
||||
};
|
||||
|
||||
typedef OffsetListOf<Lookup> LookupList;
|
||||
@ -262,6 +308,7 @@ struct CoverageRangeRecord
|
||||
return NOT_COVERED;
|
||||
}
|
||||
|
||||
public:
|
||||
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||
return SANITIZE_SELF ();
|
||||
}
|
||||
@ -376,6 +423,7 @@ struct ClassRangeRecord
|
||||
return 0;
|
||||
}
|
||||
|
||||
public:
|
||||
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||
return SANITIZE_SELF ();
|
||||
}
|
||||
|
@ -264,7 +264,7 @@ struct GDEF
|
||||
ComponentGlyph = 4,
|
||||
};
|
||||
|
||||
STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION (GDEF, 1);
|
||||
STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION (GDEF, 1, 1);
|
||||
|
||||
inline bool has_glyph_classes () const { return glyphClassDef != 0; }
|
||||
inline hb_ot_layout_class_t get_glyph_class (hb_codepoint_t glyph) const
|
||||
|
@ -161,6 +161,11 @@ static inline bool match_lookahead (APPLY_ARG_DEF,
|
||||
|
||||
struct LookupRecord
|
||||
{
|
||||
public:
|
||||
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||
return SANITIZE_SELF ();
|
||||
}
|
||||
|
||||
USHORT sequenceIndex; /* Index into current glyph
|
||||
* sequence--first glyph = 0 */
|
||||
USHORT lookupListIndex; /* Lookup to apply to that
|
||||
@ -365,7 +370,7 @@ struct ContextFormat2
|
||||
}
|
||||
|
||||
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||
return SANITIZE_THIS2 (coverage, classDef) && SANITIZE_THIS (ruleSet);
|
||||
return SANITIZE_THIS3 (coverage, classDef, ruleSet);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -851,7 +856,7 @@ struct GSUBGPOS
|
||||
static const hb_tag_t GSUBTag = HB_TAG ('G','S','U','B');
|
||||
static const hb_tag_t GPOSTag = HB_TAG ('G','P','O','S');
|
||||
|
||||
STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION (GSUBGPOS, 1);
|
||||
STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION (GSUBGPOS, 1, 1);
|
||||
|
||||
DEFINE_TAG_LIST_INTERFACE (Script, script ); /* get_script_count (), get_script (i), get_script_tag (i) */
|
||||
DEFINE_TAG_LIST_INTERFACE (Feature, feature); /* get_feature_count(), get_feature(i), get_feature_tag(i) */
|
||||
@ -861,6 +866,12 @@ struct GSUBGPOS
|
||||
DEFINE_TAG_FIND_INTERFACE (Script, script ); /* find_script_index (), get_script_by_tag (tag) */
|
||||
DEFINE_TAG_FIND_INTERFACE (Feature, feature); /* find_feature_index(), get_feature_by_tag(tag) */
|
||||
|
||||
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||
if (!SANITIZE (version)) return false;
|
||||
if (version.major != 1) return true;
|
||||
return SANITIZE_THIS3 (scriptList, featureList, lookupList);
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVersion version; /* Version of the GSUB/GPOS table--initially set
|
||||
* to 0x00010000 */
|
||||
|
Loading…
Reference in New Issue
Block a user