diff options
author | Behdad Esfahbod <behdad@behdad.org> | 2009-08-04 02:09:34 -0400 |
---|---|---|
committer | Behdad Esfahbod <behdad@behdad.org> | 2009-08-04 02:09:34 -0400 |
commit | f786c9d501099f3c989fb6e34469381f4be8681f (patch) | |
tree | 1240c168a165976e19699c1f6f625b1d854a8d8d | |
parent | dc6fe7c38db8c74453770d74961e708722d7621e (diff) | |
download | pango-f786c9d501099f3c989fb6e34469381f4be8681f.tar.gz |
[HB] More sanitize()
-rw-r--r-- | pango/opentype/hb-open-file-private.hh | 2 | ||||
-rw-r--r-- | pango/opentype/hb-open-types-private.hh | 12 | ||||
-rw-r--r-- | pango/opentype/hb-ot-layout-common-private.hh | 64 | ||||
-rw-r--r-- | pango/opentype/hb-ot-layout-gdef-private.hh | 2 | ||||
-rw-r--r-- | pango/opentype/hb-ot-layout-gsubgpos-private.hh | 15 |
5 files changed, 79 insertions, 16 deletions
diff --git a/pango/opentype/hb-open-file-private.hh b/pango/opentype/hb-open-file-private.hh index c06bb887..50b9bc20 100644 --- a/pango/opentype/hb-open-file-private.hh +++ b/pango/opentype/hb-open-file-private.hh @@ -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' */ diff --git a/pango/opentype/hb-open-types-private.hh b/pango/opentype/hb-open-types-private.hh index a8549e2b..3d57122a 100644 --- a/pango/opentype/hb-open-types-private.hh +++ b/pango/opentype/hb-open-types-private.hh @@ -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; diff --git a/pango/opentype/hb-ot-layout-common-private.hh b/pango/opentype/hb-ot-layout-common-private.hh index 3eb0a559..439d7e87 100644 --- a/pango/opentype/hb-ot-layout-common-private.hh +++ b/pango/opentype/hb-ot-layout-common-private.hh @@ -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 (); } diff --git a/pango/opentype/hb-ot-layout-gdef-private.hh b/pango/opentype/hb-ot-layout-gdef-private.hh index 560a07e2..1d1a88ee 100644 --- a/pango/opentype/hb-ot-layout-gdef-private.hh +++ b/pango/opentype/hb-ot-layout-gdef-private.hh @@ -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 diff --git a/pango/opentype/hb-ot-layout-gsubgpos-private.hh b/pango/opentype/hb-ot-layout-gsubgpos-private.hh index a14166c7..792a7d78 100644 --- a/pango/opentype/hb-ot-layout-gsubgpos-private.hh +++ b/pango/opentype/hb-ot-layout-gsubgpos-private.hh @@ -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 */ |