[cbdt] Start fixing sanitization (or lack thereof)
authorBehdad Esfahbod <behdad@behdad.org>
Sat, 3 Dec 2016 03:25:54 +0000 (19:25 -0800)
committerBehdad Esfahbod <behdad@behdad.org>
Sat, 3 Dec 2016 03:25:54 +0000 (19:25 -0800)
src/hb-ot-cbdt-table.hh
src/hb-ot-font.cc

index 7615138..dda42f2 100644 (file)
@@ -33,6 +33,12 @@ namespace OT {
 
 struct SmallGlyphMetrics
 {
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
   BYTE height;
   BYTE width;
   CHAR bearingX;
@@ -42,7 +48,14 @@ struct SmallGlyphMetrics
   DEFINE_SIZE_STATIC(5);
 };
 
-struct SBitLineMetrics {
+struct SBitLineMetrics
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
   CHAR ascender;
   CHAR decender;
   BYTE widthMax;
@@ -61,6 +74,14 @@ struct SBitLineMetrics {
 
 struct BitmapSizeTable
 {
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                 horizontal.sanitize (c) &&
+                 vertical.sanitize (c));
+  }
+
   ULONG indexSubtableArrayOffset;
   ULONG indexTablesSize;
   ULONG numberOfIndexSubtables;
@@ -94,41 +115,49 @@ struct IndexSubHeader
   USHORT indexFormat;
   USHORT imageFormat;
   ULONG imageDataOffset;
+
+  DEFINE_SIZE_STATIC(8);
 };
 
 struct IndexSubtableFormat1
 {
   IndexSubHeader header;
-  ULONG offsetArray[VAR];
+  ULONG offsetArrayZ[VAR];
+
+  DEFINE_SIZE_ARRAY(8, offsetArrayZ);
 };
 
 /*
  * Glyph Bitmap Data Formats.
  */
+
 struct GlyphBitmapDataFormat17
 {
   SmallGlyphMetrics glyphMetrics;
   ULONG dataLen;
-  BYTE data[VAR];
+  BYTE dataZ[VAR];
+
+  DEFINE_SIZE_ARRAY(9, dataZ);
 };
 
 struct IndexSubtableArray
 {
   public:
-  const IndexSubtable* find_table(hb_codepoint_t glyph, unsigned int numTables) const
+  const IndexSubtable* find_table (hb_codepoint_t glyph, unsigned int numTables) const
   {
-    for (unsigned int i = 0; i < numTables; ++i) {
-      unsigned int firstGlyphIndex = indexSubtables[i].firstGlyphIndex;
-      unsigned int lastGlyphIndex = indexSubtables[i].lastGlyphIndex;
+    for (unsigned int i = 0; i < numTables; ++i)
+    {
+      unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex;
+      unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex;
       if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex) {
-        return &indexSubtables[i];
+        return &indexSubtablesZ[i];
       }
     }
     return NULL;
   }
 
   protected:
-  IndexSubtable indexSubtables[VAR];
+  IndexSubtable indexSubtablesZ[VAR];
 };
 
 /*
@@ -144,17 +173,19 @@ struct CBLC
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (true);
+    return_trace (c->check_struct (this) &&
+                 likely (version.major == 2 || version.major == 3) &&
+                 sizeTables.sanitize (c));
   }
 
   public:
-  const BitmapSizeTable* find_table(hb_codepoint_t glyph) const
+  const BitmapSizeTable* find_table (hb_codepoint_t glyph) const
   {
     // TODO: Make it possible to select strike.
-    const uint32_t tableSize = numSizes;
-    for (uint32_t i = 0; i < tableSize; ++i) {
-      unsigned int startGlyphIndex = sizeTables[i].startGlyphIndex;
-      unsigned int endGlyphIndex = sizeTables[i].endGlyphIndex;
+    unsigned int count = sizeTables.len;
+    for (uint32_t i = 0; i < count; ++i) {
+      unsigned int startGlyphIndex = sizeTables.array[i].startGlyphIndex;
+      unsigned int endGlyphIndex = sizeTables.array[i].endGlyphIndex;
       if (startGlyphIndex <= glyph && glyph <= endGlyphIndex) {
         return &sizeTables[i];
       }
@@ -163,10 +194,11 @@ struct CBLC
   }
 
   protected:
-  ULONG version;
-  ULONG numSizes;
+  FixedVersion<>version;
+  ArrayOf<BitmapSizeTable, ULONG> sizeTables;
 
-  BitmapSizeTable sizeTables[VAR];
+  public:
+  DEFINE_SIZE_ARRAY(8, sizeTables);
 };
 
 /*
@@ -181,11 +213,16 @@ struct CBDT
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (true);
+    return_trace (c->check_struct (this) &&
+                 likely (version.major == 2 || version.major == 3));
   }
 
   protected:
-  BYTE data[VAR];
+  FixedVersion<>version;
+  BYTE dataZ[VAR];
+
+  public:
+  DEFINE_SIZE_ARRAY(4, dataZ);
 };
 
 } /* namespace OT */
index c53fcd5..25a1ef6 100644 (file)
@@ -210,10 +210,10 @@ struct hb_ot_face_glyf_accelerator_t
 
 struct hb_ot_face_cbdt_accelerator_t
 {
-  hb_blob_t *cblc_blob = NULL;
-  hb_blob_t *cbdt_blob = NULL;
-  const OT::CBLC *cblc = NULL;
-  const OT::CBDT *cbdt = NULL;
+  hb_blob_t *cblc_blob;
+  hb_blob_t *cbdt_blob;
+  const OT::CBLC *cblc;
+  const OT::CBDT *cbdt;
 
   float upem = 0.0f;
 
@@ -223,6 +223,8 @@ struct hb_ot_face_cbdt_accelerator_t
     this->cbdt_blob = OT::Sanitizer<OT::CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT));
 
     if (hb_blob_get_length (this->cblc_blob) == 0) {
+      cblc = NULL;
+      cbdt = NULL;
       return;  /* Not a bitmap font. */
     }
     cblc = OT::Sanitizer<OT::CBLC>::lock_instance (this->cblc_blob);
@@ -233,10 +235,8 @@ struct hb_ot_face_cbdt_accelerator_t
 
   inline void fini (void)
   {
-    if (this->cblc_blob) {
-      hb_blob_destroy (this->cblc_blob);
-      hb_blob_destroy (this->cbdt_blob);
-    }
+    hb_blob_destroy (this->cblc_blob);
+    hb_blob_destroy (this->cbdt_blob);
   }
 
   inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
@@ -266,7 +266,7 @@ struct hb_ot_face_cbdt_accelerator_t
       case 1: {
         const OT::IndexSubtableFormat1& format1 =
             OT::StructAtOffset<OT::IndexSubtableFormat1> (this->cblc, offsetToSubtable);
-        imageDataOffset += format1.offsetArray[glyph - subtable->firstGlyphIndex];
+        imageDataOffset += format1.offsetArrayZ[glyph - subtable->firstGlyphIndex];
         switch (header.imageFormat) {
           case 17: {
             const OT::GlyphBitmapDataFormat17& glyphFormat17 =
@@ -288,7 +288,7 @@ struct hb_ot_face_cbdt_accelerator_t
         return false;
     }
 
-    // Convert to the font units.
+    /* Convert to the font units. */
     extents->x_bearing *= upem / (float)(sizeTable->ppemX);
     extents->y_bearing *= upem / (float)(sizeTable->ppemY);
     extents->width *= upem / (float)(sizeTable->ppemX);
@@ -558,7 +558,7 @@ hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED,
 {
   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
   bool ret = ot_font->glyf->get_extents (glyph, extents);
-  if ( !ret )
+  if (!ret)
     ret = ot_font->cbdt->get_extents (glyph, extents);
   extents->x_bearing = font->em_scale_x (extents->x_bearing);
   extents->y_bearing = font->em_scale_y (extents->y_bearing);