From: Behdad Esfahbod Date: Tue, 4 Aug 2009 17:30:49 +0000 (-0400) Subject: [HB] GPOS sanitize() X-Git-Tag: 1.25.1~60 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=36c73171738ce9e51c370ad54753a8f882172e75;p=platform%2Fupstream%2Fpango.git [HB] GPOS sanitize() --- diff --git a/pango/opentype/hb-open-types-private.hh b/pango/opentype/hb-open-types-private.hh index 2c39c35..bf8b77d 100644 --- a/pango/opentype/hb-open-types-private.hh +++ b/pango/opentype/hb-open-types-private.hh @@ -68,11 +68,14 @@ struct _hb_sanitize_context_t context #define SANITIZE(X) HB_LIKELY ((X).sanitize (SANITIZE_ARG)) -#define SANITIZE2(X,Y) SANITIZE (X) && SANITIZE (Y) +#define SANITIZE2(X,Y) (SANITIZE (X) && SANITIZE (Y)) #define SANITIZE_THIS(X) HB_LIKELY ((X).sanitize (SANITIZE_ARG, CONST_CHARP(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_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_BASE(X,B) HB_LIKELY ((X).sanitize (SANITIZE_ARG, B)) +#define SANITIZE_BASE2(X,Y,B) (SANITIZE_BASE (X,B) && SANITIZE_BASE (Y,B)) #define SANITIZE_SELF() SANITIZE_OBJ (*this) #define SANITIZE_OBJ(X) SANITIZE_MEM(&(X), sizeof (X)) @@ -351,6 +354,12 @@ struct GenericOffsetTo : OffsetType if (HB_UNLIKELY (!offset)) return true; return SANITIZE (CAST(Type, *DECONST_CHARP(base), offset)) || NEUTER (*this, 0); } + inline bool sanitize (SANITIZE_ARG_DEF, const void *base, unsigned int user_data) { + if (!SANITIZE_OBJ (*this)) return false; + unsigned int offset = *this; + if (HB_UNLIKELY (!offset)) return true; + return SANITIZE_BASE (CAST(Type, *DECONST_CHARP(base), offset), user_data) || NEUTER (*this, 0); + } }; template inline const Type& operator + (const Base &base, GenericOffsetTo offset) { return offset (base); } @@ -391,6 +400,13 @@ struct GenericArrayOf if (!array[i].sanitize (SANITIZE_ARG, base)) return false; } + inline bool sanitize (SANITIZE_ARG_DEF, const void *base, unsigned int user_data) { + if (!SANITIZE_GET_SIZE()) return false; + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + if (!array[i].sanitize (SANITIZE_ARG, base, user_data)) + return false; + } LenType len; Type array[]; diff --git a/pango/opentype/hb-ot-layout-gpos-private.hh b/pango/opentype/hb-ot-layout-gpos-private.hh index f43aa2d..d45feec 100644 --- a/pango/opentype/hb-ot-layout-gpos-private.hh +++ b/pango/opentype/hb-ot-layout-gpos-private.hh @@ -54,6 +54,8 @@ struct ValueFormat : USHORT inline unsigned int get_len () const { return _hb_popcount32 ((unsigned int) *this); } + inline unsigned int get_size () const + { return get_len () * sizeof (Value); } const void apply_value (hb_ot_layout_context_t *context, const char *base, @@ -153,6 +155,10 @@ struct AnchorFormat1 *y = context->font->y_scale * yCoordinate / 0x10000; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_SELF (); + } + private: USHORT format; /* Format identifier--format = 1 */ SHORT xCoordinate; /* Horizontal value--in design units */ @@ -173,6 +179,10 @@ struct AnchorFormat2 *y = context->font->y_scale * yCoordinate / 0x10000; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_SELF (); + } + private: USHORT format; /* Format identifier--format = 2 */ SHORT xCoordinate; /* Horizontal value--in design units */ @@ -198,6 +208,10 @@ struct AnchorFormat3 *y += (this+yDeviceTable).get_delta (context->font->y_ppem) << 6; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_SELF () && SANITIZE_THIS2 (xDeviceTable, yDeviceTable); + } + private: USHORT format; /* Format identifier--format = 3 */ SHORT xCoordinate; /* Horizontal value--in design units */ @@ -227,6 +241,16 @@ struct Anchor } } + 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 */ @@ -242,6 +266,10 @@ struct MarkRecord { friend struct MarkArray; + inline bool sanitize (SANITIZE_ARG_DEF, const void *base) { + return SANITIZE_SELF () && SANITIZE_BASE (markAnchor, base); + } + private: USHORT klass; /* Class defined for this mark */ OffsetTo @@ -255,6 +283,10 @@ struct MarkArray inline unsigned int get_class (unsigned int index) const { return markRecord[index].klass; } inline const Anchor& get_anchor (unsigned int index) const { return this+markRecord[index].markAnchor; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_THIS (markRecord); + } + private: ArrayOf markRecord; /* Array of MarkRecords--in Coverage order */ @@ -281,6 +313,11 @@ struct SinglePosFormat1 return true; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_SELF () && SANITIZE_THIS (coverage) && + SANITIZE_MEM (values, valueFormat.get_size ()); + } + private: USHORT format; /* Format identifier--format = 1 */ OffsetTo @@ -316,6 +353,11 @@ struct SinglePosFormat2 return true; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_SELF () && SANITIZE_THIS (coverage) && + SANITIZE_MEM (values, valueFormat.get_size () * valueCount); + } + private: USHORT format; /* Format identifier--format = 2 */ OffsetTo @@ -343,6 +385,15 @@ struct SinglePos } } + 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 */ @@ -370,6 +421,12 @@ struct PairSet { friend struct PairPosFormat1; + inline bool sanitize (SANITIZE_ARG_DEF, unsigned int format_len) { + if (!SANITIZE_SELF ()) return false; + unsigned int count = (1 + format_len) * len; + return SANITIZE_MEM (array, sizeof (array[0]) * count); + } + private: USHORT len; /* Number of PairValueRecords */ PairValueRecord @@ -426,6 +483,12 @@ struct PairPosFormat1 return false; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_SELF () && SANITIZE_THIS (coverage) && + pairSet.sanitize (SANITIZE_ARG, CONST_CHARP(this), + valueFormat1.get_len () + valueFormat2.get_len ()); + } + private: USHORT format; /* Format identifier--format = 1 */ OffsetTo @@ -486,6 +549,13 @@ struct PairPosFormat2 return true; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_SELF () && SANITIZE_THIS (coverage) && + SANITIZE_THIS2 (classDef1, classDef2) && + SANITIZE_MEM (values, + (valueFormat1.get_size () + valueFormat2.get_size ()) * + class1Count * class2Count); + } private: USHORT format; /* Format identifier--format = 2 */ @@ -530,6 +600,15 @@ struct PairPos } } + 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 */ @@ -542,6 +621,10 @@ ASSERT_SIZE (PairPos, 2); struct EntryExitRecord { + inline bool sanitize (SANITIZE_ARG_DEF, const void *base) { + return SANITIZE_BASE2 (entryAnchor, exitAnchor, base); + } + OffsetTo entryAnchor; /* Offset to EntryAnchor table--from * beginning of CursivePos @@ -732,6 +815,10 @@ struct CursivePosFormat1 return true; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_THIS2 (coverage, entryExitRecord); + } + private: USHORT format; /* Format identifier--format = 1 */ OffsetTo @@ -756,6 +843,14 @@ struct CursivePos } } + 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 */ @@ -769,6 +864,15 @@ struct BaseArray { friend struct MarkBasePosFormat1; + inline bool sanitize (SANITIZE_ARG_DEF, unsigned int cols) { + if (!SANITIZE_SELF ()) return false; + unsigned int count = cols * len; + if (!SANITIZE_MEM (matrix, sizeof (matrix[0]) * count)) return false; + for (unsigned int i = 0; i < count; i++) + if (!SANITIZE_THIS (matrix[i])) return false; + return true; + } + private: USHORT len; /* Number of rows */ OffsetTo @@ -836,6 +940,11 @@ struct MarkBasePosFormat1 return true; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_SELF () && SANITIZE_THIS2 (markCoverage, baseCoverage) && + SANITIZE_THIS (markArray) && baseArray.sanitize (SANITIZE_ARG, CONST_CHARP(this), classCount); + } + private: USHORT format; /* Format identifier--format = 1 */ OffsetTo @@ -867,6 +976,14 @@ struct MarkBasePos } } + 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 */ @@ -973,6 +1090,12 @@ struct MarkLigPosFormat1 return true; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_SELF () && + SANITIZE_THIS2 (markCoverage, ligatureCoverage) && + SANITIZE_THIS2 (markArray, ligatureArray); + } + private: USHORT format; /* Format identifier--format = 1 */ OffsetTo @@ -1005,6 +1128,14 @@ struct MarkLigPos } } + 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 */ @@ -1018,6 +1149,15 @@ struct Mark2Array { friend struct MarkMarkPosFormat1; + inline bool sanitize (SANITIZE_ARG_DEF, unsigned int cols) { + if (!SANITIZE_SELF ()) return false; + unsigned int count = cols * len; + if (!SANITIZE_MEM (matrix, sizeof (matrix[0]) * count)) return false; + for (unsigned int i = 0; i < count; i++) + if (!SANITIZE_THIS (matrix[i])) return false; + return true; + } + private: USHORT len; /* Number of rows */ OffsetTo @@ -1088,6 +1228,11 @@ struct MarkMarkPosFormat1 return true; } + inline bool sanitize (SANITIZE_ARG_DEF) { + return SANITIZE_SELF () && SANITIZE_THIS2 (mark1Coverage, mark2Coverage) && + SANITIZE_THIS (mark1Array) && mark2Array.sanitize (SANITIZE_ARG, CONST_CHARP(this), classCount); + } + private: USHORT format; /* Format identifier--format = 1 */ OffsetTo @@ -1121,6 +1266,14 @@ struct MarkMarkPos } } + 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 */ @@ -1158,7 +1311,12 @@ struct ExtensionPos : Extension friend struct PosLookupSubTable; private: + inline const struct PosLookupSubTable& get_subtable (void) const + { return CONST_CAST (PosLookupSubTable, Extension::get_subtable (), 0); } + inline bool apply (APPLY_ARG_DEF) const; + + inline bool sanitize (SANITIZE_ARG_DEF); }; ASSERT_SIZE (ExtensionPos, 2); @@ -1201,6 +1359,22 @@ struct PosLookupSubTable } } + bool sanitize (SANITIZE_ARG_DEF) { + if (!SANITIZE (u.format)) return false; + switch (u.format) { + case Single: return u.single->sanitize (SANITIZE_ARG); + case Pair: return u.pair->sanitize (SANITIZE_ARG); + case Cursive: return u.cursive->sanitize (SANITIZE_ARG); + case MarkBase: return u.markBase->sanitize (SANITIZE_ARG); + case MarkLig: return u.markLig->sanitize (SANITIZE_ARG); + case MarkMark: return u.markMark->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); + default:return true; + } + } + private: union { USHORT format; @@ -1296,9 +1470,17 @@ struct PosLookup : Lookup return ret; } + + inline bool sanitize (SANITIZE_ARG_DEF) { + if (Lookup::sanitize (SANITIZE_ARG)) return false; + OffsetArrayOf &list = (OffsetArrayOf &) subTable; + return SANITIZE_THIS (list); + } }; ASSERT_SIZE (PosLookup, 6); +typedef OffsetListOf PosLookupList; +ASSERT_SIZE (PosLookupList, 2); /* * GPOS @@ -1320,6 +1502,11 @@ struct GPOS : GSUBGPOS hb_ot_layout_feature_mask_t mask) const { return get_lookup (lookup_index).apply_string (context, buffer, mask); } + inline bool sanitize (SANITIZE_ARG_DEF) { + if (GSUBGPOS::sanitize (SANITIZE_ARG)) return false; + OffsetTo &list = CAST(OffsetTo, lookupList, 0); + return SANITIZE_THIS (list); + } }; ASSERT_SIZE (GPOS, 10); @@ -1333,7 +1520,13 @@ inline bool ExtensionPos::apply (APPLY_ARG_DEF) const if (HB_UNLIKELY (lookup_type == PosLookupSubTable::Extension)) return false; - return ((PosLookupSubTable&) get_subtable ()).apply (APPLY_ARG, lookup_type); + return get_subtable ().apply (APPLY_ARG, lookup_type); +} + +inline bool ExtensionPos::sanitize (SANITIZE_ARG_DEF) +{ + return Extension::sanitize (SANITIZE_ARG) && + DECONST_CAST (PosLookupSubTable, get_subtable (), 0).sanitize (SANITIZE_ARG); } static inline bool position_lookup (APPLY_ARG_DEF, unsigned int lookup_index) diff --git a/pango/opentype/hb-ot-layout-gsub-private.hh b/pango/opentype/hb-ot-layout-gsub-private.hh index 91a2564..b221f6f 100644 --- a/pango/opentype/hb-ot-layout-gsub-private.hh +++ b/pango/opentype/hb-ot-layout-gsub-private.hh @@ -830,8 +830,6 @@ struct GSUB : GSUBGPOS inline const SubstLookup& get_lookup (unsigned int i) const { return (const SubstLookup&) GSUBGPOS::get_lookup (i); } - inline SubstLookup& get_lookup (unsigned int i) - { return (SubstLookup&) GSUBGPOS::get_lookup (i); } inline bool substitute_lookup (hb_ot_layout_context_t *context, hb_buffer_t *buffer,