[pango/harfbuzz-ng: 48/57] [HB] GPOS sanitize()



commit 36c73171738ce9e51c370ad54753a8f882172e75
Author: Behdad Esfahbod <behdad behdad org>
Date:   Tue Aug 4 13:30:49 2009 -0400

    [HB] GPOS sanitize()

 pango/opentype/hb-open-types-private.hh     |   22 +++-
 pango/opentype/hb-ot-layout-gpos-private.hh |  195 ++++++++++++++++++++++++++-
 pango/opentype/hb-ot-layout-gsub-private.hh |    2 -
 3 files changed, 213 insertions(+), 6 deletions(-)
---
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 <typename Base, typename OffsetType, typename Type>
 inline const Type& operator + (const Base &base, GenericOffsetTo<OffsetType, Type> 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<Anchor>
@@ -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>
 		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<Coverage>
@@ -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<Coverage>
@@ -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<Coverage>
@@ -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<Anchor>
 		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<Coverage>
@@ -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<Anchor>
@@ -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<Coverage>
@@ -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<Coverage>
@@ -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<Anchor>
@@ -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<Coverage>
@@ -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<PosLookupSubTable> &list = (OffsetArrayOf<PosLookupSubTable> &) subTable;
+    return SANITIZE_THIS (list);
+  }
 };
 ASSERT_SIZE (PosLookup, 6);
 
+typedef OffsetListOf<PosLookup> 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<PosLookupList> &list = CAST(OffsetTo<PosLookupList>, 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,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]