From dc6fe7c38db8c74453770d74961e708722d7621e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 4 Aug 2009 00:58:28 -0400 Subject: [HB] Start sanitize() --- pango/opentype/hb-open-types-private.hh | 105 +++++++++++++++++++- pango/opentype/hb-ot-layout-common-private.hh | 48 ++++++++- pango/opentype/hb-ot-layout-gsub-private.hh | 125 +++++++++++++++++++++++- pango/opentype/hb-ot-layout-gsubgpos-private.hh | 104 ++++++++++++++++++++ 4 files changed, 376 insertions(+), 6 deletions(-) diff --git a/pango/opentype/hb-open-types-private.hh b/pango/opentype/hb-open-types-private.hh index 98efde47..a8549e2b 100644 --- a/pango/opentype/hb-open-types-private.hh +++ b/pango/opentype/hb-open-types-private.hh @@ -29,6 +29,8 @@ #include "hb-private.h" +#include "hb-blob.h" + #define NO_INDEX ((unsigned int) 0xFFFF) #define NO_CONTEXT ((unsigned int) 0x110000) @@ -36,6 +38,38 @@ #define MAX_NESTING_LEVEL 8 + +/* + * Sanitize + */ + +typedef struct _hb_sanitize_context_t hb_sanitize_context_t; +struct _hb_sanitize_context_t +{ + const char *start, *end; + hb_blob_t *blob; +}; + +#define SANITIZE_ARG_DEF \ + hb_sanitize_context_t *context +#define SANITIZE_ARG \ + context + +#define SANITIZE(X) HB_LIKELY ((X).sanitize (SANITIZE_ARG)) +#define SANITIZE2(X,Y) SANITIZE (X) && SANITIZE (Y) + +#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_SELF() SANITIZE_OBJ (*this) +#define SANITIZE_OBJ(X) SANITIZE_MEM(&(X), sizeof (X)) +#define SANITIZE_GET_SIZE() SANITIZE_MEM (this, this->get_size ()) + +#define SANITIZE_MEM(B,L) HB_LIKELY (context->start <= (const char *)(B) && (const char *)(B) + (L) <= context->end) /* XXX overflow */ + +#define NEUTER(Var, Val) (false) + + /* * Array types */ @@ -208,6 +242,7 @@ struct Null \ inline NAME& operator = (TYPE i) { (TYPE&) v = BIG_ENDIAN (i); return *this; } \ inline operator TYPE(void) const { return BIG_ENDIAN ((TYPE&) v); } \ inline bool operator== (NAME o) const { return (TYPE&) v == (TYPE&) o.v; } \ + inline bool sanitize (SANITIZE_ARG_DEF) { return SANITIZE_SELF (); } \ private: char v[BYTES]; \ }; \ ASSERT_SIZE (NAME, BYTES) @@ -257,6 +292,13 @@ struct OffsetTo : Offset if (HB_UNLIKELY (!offset)) return Null(Type); return *(const Type*)((const char *) base + offset); } + + inline bool sanitize (SANITIZE_ARG_DEF, const void *base) { + if (!SANITIZE_OBJ (*this)) return false; + unsigned int offset = *this; + if (HB_UNLIKELY (!offset)) return true; + return SANITIZE (*(Type*)((char *) base + offset)) || NEUTER (*this, 0); + } }; template inline const Type& operator + (const Base &base, OffsetTo offset) { return offset (base); } @@ -270,6 +312,13 @@ struct LongOffsetTo : LongOffset if (HB_UNLIKELY (!offset)) return Null(Type); return *(const Type*)((const char *) base + offset); } + + inline bool sanitize (SANITIZE_ARG_DEF, const void *base) { + if (!SANITIZE (*this)) return false; + unsigned int offset = *this; + if (HB_UNLIKELY (!offset)) return true; + return SANITIZE (*(Type*)((char *) base + offset)) || NEUTER (*this, 0); + } }; template inline const Type& operator + (const Base &base, LongOffsetTo offset) { return offset (base); } @@ -320,6 +369,16 @@ struct ArrayOf inline unsigned int get_size () const { return sizeof (len) + len * sizeof (array[0]); } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!(SANITIZE (len) && SANITIZE_GET_SIZE())) return false; + /* For non-offset types, this shouldn't be needed + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + if (!SANITIZE (array[i])) + return false; + */ + } + USHORT len; Type array[]; }; @@ -337,6 +396,14 @@ struct HeadlessArrayOf inline unsigned int get_size () const { return sizeof (len) + (len ? len - 1 : 0) * sizeof (array[0]); } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!(SANITIZE_SELF () && SANITIZE_GET_SIZE())) return false; + unsigned int count = len ? len - 1 : 0; + for (unsigned int i = 0; i < count; i++) + if (!SANITIZE (array[i])) + return false; + } + USHORT len; Type array[]; }; @@ -353,21 +420,53 @@ struct LongArrayOf inline unsigned int get_size () const { return sizeof (len) + len * sizeof (array[0]); } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!(SANITIZE_SELF () && SANITIZE_GET_SIZE())) return false; + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + if (!SANITIZE (array[i])) + return false; + } + ULONG len; Type array[]; }; /* Array of Offset's */ template -struct OffsetArrayOf : ArrayOf > {}; +struct OffsetArrayOf : ArrayOf > { + 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 (!this->array[i].sanitize (SANITIZE_ARG, base)) + return false; + } +}; /* Array of LongOffset's */ template -struct LongOffsetArrayOf : ArrayOf > {}; +struct LongOffsetArrayOf : ArrayOf > { + 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 (!this->array[i].sanitize (SANITIZE_ARG, base)) + return false; + } +}; /* LongArray of LongOffset's */ template -struct LongOffsetLongArrayOf : LongArrayOf > {}; +struct LongOffsetLongArrayOf : LongArrayOf > { + 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 (!this->array[i].sanitize (SANITIZE_ARG, base)) + return false; + } +}; /* An array type is one that contains a variable number of objects * as its last item. An array object is extended with get_len() diff --git a/pango/opentype/hb-ot-layout-common-private.hh b/pango/opentype/hb-ot-layout-common-private.hh index 8f24fadf..3eb0a559 100644 --- a/pango/opentype/hb-ot-layout-common-private.hh +++ b/pango/opentype/hb-ot-layout-common-private.hh @@ -239,6 +239,11 @@ struct CoverageFormat1 return NOT_COVERED; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE (glyphArray); + } + + private: USHORT coverageFormat; /* Format identifier--format = 1 */ ArrayOf glyphArray; /* Array of GlyphIDs--in numerical order */ @@ -257,6 +262,10 @@ struct CoverageRangeRecord return NOT_COVERED; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_SELF (); + } + private: GlyphID start; /* First GlyphID in the range */ GlyphID end; /* Last GlyphID in the range */ @@ -283,6 +292,11 @@ struct CoverageFormat2 return NOT_COVERED; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE (rangeRecord); + } + + private: USHORT coverageFormat; /* Format identifier--format = 2 */ ArrayOf rangeRecord; /* Array of glyph ranges--ordered by @@ -293,6 +307,8 @@ ASSERT_SIZE (CoverageFormat2, 4); struct Coverage { + inline unsigned int operator() (hb_codepoint_t glyph_id) const { return get_coverage (glyph_id); } + unsigned int get_coverage (hb_codepoint_t glyph_id) const { switch (u.format) { @@ -302,7 +318,14 @@ struct Coverage } } - inline unsigned int operator() (hb_codepoint_t glyph_id) const { return get_coverage (glyph_id); } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!SANITIZE (u.format)) return false; + switch (u.format) { + case 1: return u.format1->sanitize (SANITIZE_ARG); + case 2: return u.format2->sanitize (SANITIZE_ARG); + default:return true; + } + } private: union { @@ -330,6 +353,10 @@ struct ClassDefFormat1 return 0; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_SELF () && SANITIZE (classValue); + } + USHORT classFormat; /* Format identifier--format = 1 */ GlyphID startGlyph; /* First GlyphID of the classValueArray */ ArrayOf @@ -349,6 +376,10 @@ struct ClassRangeRecord return 0; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_SELF (); + } + private: GlyphID start; /* First GlyphID in the range */ GlyphID end; /* Last GlyphID in the range */ @@ -374,6 +405,10 @@ struct ClassDefFormat2 return 0; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE (rangeRecord); + } + USHORT classFormat; /* Format identifier--format = 2 */ ArrayOf rangeRecord; /* Array of glyph ranges--ordered by @@ -383,6 +418,8 @@ ASSERT_SIZE (ClassDefFormat2, 4); struct ClassDef { + inline unsigned int operator() (hb_codepoint_t glyph_id) const { return get_class (glyph_id); } + hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const { switch (u.format) { @@ -392,7 +429,14 @@ struct ClassDef } } - inline unsigned int operator() (hb_codepoint_t glyph_id) const { return get_class (glyph_id); } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!SANITIZE (u.format)) return false; + switch (u.format) { + case 1: return u.format1->sanitize (SANITIZE_ARG); + case 2: return u.format2->sanitize (SANITIZE_ARG); + default:return true; + } + } private: union { diff --git a/pango/opentype/hb-ot-layout-gsub-private.hh b/pango/opentype/hb-ot-layout-gsub-private.hh index 37cc00b5..af58a1fe 100644 --- a/pango/opentype/hb-ot-layout-gsub-private.hh +++ b/pango/opentype/hb-ot-layout-gsub-private.hh @@ -35,6 +35,7 @@ struct SingleSubstFormat1 friend struct SingleSubst; private: + inline bool apply (APPLY_ARG_DEF) const { hb_codepoint_t glyph_id = IN_CURGLYPH (); @@ -52,6 +53,10 @@ struct SingleSubstFormat1 return true; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_THIS (coverage) && SANITIZE (deltaGlyphID); + } + private: USHORT format; /* Format identifier--format = 1 */ OffsetTo @@ -67,6 +72,7 @@ struct SingleSubstFormat2 friend struct SingleSubst; private: + inline bool apply (APPLY_ARG_DEF) const { hb_codepoint_t glyph_id = IN_CURGLYPH (); @@ -87,6 +93,10 @@ struct SingleSubstFormat2 return true; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_THIS (coverage) && SANITIZE (substitute); + } + private: USHORT format; /* Format identifier--format = 2 */ OffsetTo @@ -103,6 +113,7 @@ struct SingleSubst friend struct SubstLookupSubTable; private: + inline bool apply (APPLY_ARG_DEF) const { switch (u.format) { @@ -112,6 +123,15 @@ struct SingleSubst } } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!SANITIZE (u.format)) return false; + switch (u.format) { + case 1: return u.format1->sanitize (SANITIZE_ARG); + case 2: return u.format2->sanitize (SANITIZE_ARG); + default:return true; + } + } + private: union { USHORT format; /* Format identifier */ @@ -150,6 +170,11 @@ struct Sequence return true; } + public: + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE (substitute); + } + private: ArrayOf substitute; /* String of GlyphIDs to substitute */ @@ -161,6 +186,7 @@ struct MultipleSubstFormat1 friend struct MultipleSubst; private: + inline bool apply (APPLY_ARG_DEF) const { @@ -171,6 +197,10 @@ struct MultipleSubstFormat1 return (this+sequence[index]).apply (APPLY_ARG); } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_THIS2 (coverage, sequence); + } + private: USHORT format; /* Format identifier--format = 1 */ OffsetTo @@ -187,6 +217,7 @@ struct MultipleSubst friend struct SubstLookupSubTable; private: + inline bool apply (APPLY_ARG_DEF) const { switch (u.format) { @@ -195,6 +226,14 @@ struct MultipleSubst } } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!SANITIZE (u.format)) return false; + switch (u.format) { + case 1: return u.format1->sanitize (SANITIZE_ARG); + default:return true; + } + } + private: union { USHORT format; /* Format identifier */ @@ -213,6 +252,7 @@ struct AlternateSubstFormat1 friend struct AlternateSubst; private: + inline bool apply (APPLY_ARG_DEF) const { hb_codepoint_t glyph_id = IN_CURGLYPH (); @@ -249,6 +289,10 @@ struct AlternateSubstFormat1 return true; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_THIS2 (coverage, alternateSet); + } + private: USHORT format; /* Format identifier--format = 1 */ OffsetTo @@ -265,6 +309,7 @@ struct AlternateSubst friend struct SubstLookupSubTable; private: + inline bool apply (APPLY_ARG_DEF) const { switch (u.format) { @@ -273,6 +318,14 @@ struct AlternateSubst } } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!SANITIZE (u.format)) return false; + switch (u.format) { + case 1: return u.format1->sanitize (SANITIZE_ARG); + default:return true; + } + } + private: union { USHORT format; /* Format identifier */ @@ -352,6 +405,11 @@ struct Ligature return true; } + public: + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE2 (ligGlyph, component); + } + private: GlyphID ligGlyph; /* GlyphID of ligature to substitute */ HeadlessArrayOf @@ -379,6 +437,11 @@ struct LigatureSet return false; } + public: + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_THIS (ligature); + } + private: OffsetArrayOf ligature; /* Array LigatureSet tables @@ -405,6 +468,10 @@ struct LigatureSubstFormat1 return lig_set.apply (APPLY_ARG, first_is_mark); } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_THIS2 (coverage, ligatureSet); + } + private: USHORT format; /* Format identifier--format = 1 */ OffsetTo @@ -429,6 +496,14 @@ struct LigatureSubst } } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!SANITIZE (u.format)) return false; + switch (u.format) { + case 1: return u.format1->sanitize (SANITIZE_ARG); + default:return true; + } + } + private: union { USHORT format; /* Format identifier */ @@ -467,7 +542,14 @@ struct ExtensionSubst : Extension friend struct SubstLookupSubTable; private: + inline const struct SubstLookupSubTable& get_subtable (void) const + { return (const struct SubstLookupSubTable&) Extension::get_subtable (); } + inline struct SubstLookupSubTable& get_subtable (void) + { return (struct SubstLookupSubTable&) Extension::get_subtable (); } + inline bool apply (APPLY_ARG_DEF) const; + + inline bool sanitize (SANITIZE_ARG_DEF); }; ASSERT_SIZE (ExtensionSubst, 2); @@ -507,6 +589,19 @@ struct ReverseChainSingleSubstFormat1 return false; } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!SANITIZE_THIS2 (coverage, backtrack)) + return false; + OffsetArrayOf &lookahead = (OffsetArrayOf&) + *((const char *) &backtrack + backtrack.get_size ()); + if (!SANITIZE_THIS (lookahead)) + return false; + ArrayOf &substitute = (ArrayOf&) + *((const char *) &lookahead + lookahead.get_size ()); + if (!SANITIZE (substitute)) + return false; + } + private: USHORT format; /* Format identifier--format = 1 */ OffsetTo @@ -539,6 +634,14 @@ struct ReverseChainSingleSubst } } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!SANITIZE (u.format)) return false; + switch (u.format) { + case 1: return u.format1->sanitize (SANITIZE_ARG); + default:return true; + } + } + private: union { USHORT format; /* Format identifier */ @@ -583,6 +686,21 @@ struct SubstLookupSubTable } } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!SANITIZE (u.format)) return false; + switch (u.format) { + case Single: return u.single->sanitize (SANITIZE_ARG); + case Multiple: return u.multiple->sanitize (SANITIZE_ARG); + case Alternate: return u.alternate->sanitize (SANITIZE_ARG); + case Ligature: return u.ligature->sanitize (SANITIZE_ARG); + case Context: return u.context->sanitize (SANITIZE_ARG); + case ChainContext: return u.chainContext->sanitize (SANITIZE_ARG); + case Extension: return u.extension->sanitize (SANITIZE_ARG); + case ReverseChainSingle: return u.reverseChainContextSingle->sanitize (SANITIZE_ARG); + default:return true; + } + } + private: union { USHORT format; @@ -729,7 +847,12 @@ inline bool ExtensionSubst::apply (APPLY_ARG_DEF) const if (HB_UNLIKELY (lookup_type == SubstLookupSubTable::Extension)) return false; - return ((SubstLookupSubTable&) get_subtable ()).apply (APPLY_ARG, lookup_type); + return get_subtable ().apply (APPLY_ARG, lookup_type); +} + +inline bool ExtensionSubst::sanitize (SANITIZE_ARG_DEF) +{ + return Extension::sanitize (SANITIZE_ARG) && get_subtable ().sanitize (SANITIZE_ARG); } static inline bool substitute_lookup (APPLY_ARG_DEF, unsigned int lookup_index) diff --git a/pango/opentype/hb-ot-layout-gsubgpos-private.hh b/pango/opentype/hb-ot-layout-gsubgpos-private.hh index 13f9dbad..a14166c7 100644 --- a/pango/opentype/hb-ot-layout-gsubgpos-private.hh +++ b/pango/opentype/hb-ot-layout-gsubgpos-private.hh @@ -260,6 +260,14 @@ struct Rule lookup_context); } + public: + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!SANITIZE_SELF ()) return false; + return SANITIZE_MEM (input, + sizeof (input[0]) * inputCount + + sizeof (lookupRecordX[0]) * lookupCount); + } + private: USHORT inputCount; /* Total number of glyphs in input * glyph sequence--includes the first @@ -286,6 +294,10 @@ struct RuleSet return false; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_THIS (rule); + } + private: OffsetArrayOf rule; /* Array of Rule tables @@ -312,6 +324,10 @@ struct ContextFormat1 return rule_set.apply (APPLY_ARG, lookup_context); } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_THIS2 (coverage, ruleSet); + } + private: USHORT format; /* Format identifier--format = 1 */ OffsetTo @@ -348,6 +364,10 @@ struct ContextFormat2 return rule_set.apply (APPLY_ARG, lookup_context); } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_THIS2 (coverage, classDef) && SANITIZE_THIS (ruleSet); + } + private: USHORT format; /* Format identifier--format = 2 */ OffsetTo @@ -387,6 +407,17 @@ struct ContextFormat3 lookup_context); } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!SANITIZE_SELF ()) return false; + unsigned int count = glyphCount; + for (unsigned int i = 0; i < count; i++) + if (!SANITIZE_THIS (coverage[i])) return false; + LookupRecord *lookupRecord = (LookupRecord *) + ((char *) coverage + + sizeof (coverage[0]) * glyphCount); + return SANITIZE_MEM (lookupRecord, sizeof (lookupRecord[0]) * lookupCount); + } + private: USHORT format; /* Format identifier--format = 3 */ USHORT glyphCount; /* Number of glyphs in the input glyph @@ -413,6 +444,16 @@ struct Context } } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!SANITIZE (u.format)) return false; + switch (u.format) { + case 1: return u.format1->sanitize (SANITIZE_ARG); + case 2: return u.format2->sanitize (SANITIZE_ARG); + case 3: return u.format3->sanitize (SANITIZE_ARG); + default:return true; + } + } + private: union { USHORT format; /* Format identifier */ @@ -490,6 +531,19 @@ struct ChainRule return false; } + public: + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!SANITIZE (backtrack)) return false; + HeadlessArrayOf &input = *(HeadlessArrayOf*) + ((char *) &backtrack + backtrack.get_size ()); + if (!SANITIZE (input)) return false; + ArrayOf &lookahead = *(ArrayOf*) + ((char *) &input + input.get_size ()); + if (!SANITIZE (lookahead)) return false; + ArrayOf &lookup = *(ArrayOf*) + ((char *) &lookahead + lookahead.get_size ()); + return SANITIZE (lookup); + } private: ArrayOf @@ -522,6 +576,10 @@ struct ChainRuleSet return false; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_THIS (rule); + } + private: OffsetArrayOf rule; /* Array of ChainRule tables @@ -547,6 +605,11 @@ struct ChainContextFormat1 }; return rule_set.apply (APPLY_ARG, lookup_context); } + + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_THIS2 (coverage, ruleSet); + } + private: USHORT format; /* Format identifier--format = 1 */ OffsetTo @@ -587,6 +650,12 @@ struct ChainContextFormat2 return rule_set.apply (APPLY_ARG, lookup_context); } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_THIS2 (coverage, backtrackClassDef) && + SANITIZE_THIS2 (inputClassDef, lookaheadClassDef) && + SANITIZE_THIS (ruleSet); + } + private: USHORT format; /* Format identifier--format = 2 */ OffsetTo @@ -642,6 +711,19 @@ struct ChainContextFormat3 return false; } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!SANITIZE_THIS (backtrack)) return false; + OffsetArrayOf &input = *(OffsetArrayOf*) + ((char *) &backtrack + backtrack.get_size ()); + if (!SANITIZE_THIS (input)) return false; + OffsetArrayOf &lookahead = *(OffsetArrayOf*) + ((char *) &input + input.get_size ()); + if (!SANITIZE_THIS (lookahead)) return false; + ArrayOf &lookup = *(ArrayOf*) + ((char *) &lookahead + lookahead.get_size ()); + return SANITIZE (lookup); + } + private: USHORT format; /* Format identifier--format = 3 */ OffsetArrayOf @@ -675,6 +757,16 @@ struct ChainContext } } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!SANITIZE (u.format)) return false; + switch (u.format) { + case 1: return u.format1->sanitize (SANITIZE_ARG); + case 2: return u.format2->sanitize (SANITIZE_ARG); + case 3: return u.format3->sanitize (SANITIZE_ARG); + default:return true; + } + } + private: union { USHORT format; /* Format identifier */ @@ -700,6 +792,10 @@ struct ExtensionFormat1 return *(LookupSubTable*)(((char *) this) + offset); } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_SELF (); + } + private: USHORT format; /* Format identifier. Set to 1. */ USHORT extensionLookupType; /* Lookup type of subtable referenced @@ -729,6 +825,14 @@ struct Extension } } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (!SANITIZE (u.format)) return false; + switch (u.format) { + case 1: return u.format1->sanitize (SANITIZE_ARG); + default:return true; + } + } + private: union { USHORT format; /* Format identifier */ -- cgit v1.2.1