Added sanitize functions & calls
authorMichiharu Ariza <ariza@adobe.com>
Mon, 30 Jul 2018 21:28:40 +0000 (14:28 -0700)
committerMichiharu Ariza <ariza@adobe.com>
Mon, 30 Jul 2018 21:28:40 +0000 (14:28 -0700)
Added sanitize functions to FDSelect
Added satnitize calls for FDSelect, VariationStore, FDArray, TopDict

src/hb-ot-cff-common-private.hh
src/hb-ot-cff2-table.hh
src/hb-subset-cff2.cc

index fde100a..9dab98d 100644 (file)
@@ -23,8 +23,8 @@
  *
  * Adobe Author(s): Michiharu Ariza
  */
-#ifndef HB_OT_CFF_COMMON_HH
-#define HB_OT_CFF_COMMON_HH
+#ifndef HB_OT_CFF_COMMON_PRIVATE_HH
+#define HB_OT_CFF_COMMON_PRIVATE_HH
 
 #include "hb-open-type-private.hh"
 #include "hb-ot-layout-common-private.hh"
@@ -140,9 +140,9 @@ struct Index
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && offSize >= 1 && offSize <= 4 &&
-                  c->check_array (offsets, offSize, count + 1) &&
-                  c->check_array (data_base (), 1, offset_at (count)));
+    return_trace (likely (c->check_struct (this) && offSize >= 1 && offSize <= 4 &&
+                          c->check_array (offsets, offSize, count + 1) &&
+                          c->check_array (data_base (), 1, max_offset () - 1)));
   }
 
   inline unsigned int offset_array_size (void) const
@@ -182,6 +182,19 @@ struct Index
   inline unsigned int get_size (void) const
   { return count.static_size + offSize.static_size + offset_array_size () + (offset_at (count) - 1); }
 
+  protected:
+  inline unsigned int max_offset (void) const
+  {
+    unsigned int max = 0;
+    for (unsigned int i = 0; i <= count; i++)
+    {
+      unsigned int off = offset_at (i);
+      if (off > max) max = off;
+    }
+    return max;
+  }
+
+  public:
   HBUINT32  count;        /* Number of object data. Note there are (count+1) offsets */
   HBUINT8   offSize;      /* The byte size of each offset in the offsets array. */
   HBUINT8   offsets[VAR]; /* The array of (count + 1) offsets into objects array (1-base). */
@@ -193,14 +206,6 @@ struct Index
 template <typename Type>
 struct IndexOf : Index
 {
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && offSize >= 1 && offSize <= 4 &&
-                  c->check_array (offsets, offSize, count + 1) &&
-                  c->check_array (data_base (), sizeof (Type), offset_at (count)));
-  }
-
   inline const Type& operator [] (unsigned int index) const
   {
     if (likely (index < count))
@@ -235,27 +240,59 @@ typedef IndexOf<Dict> FDArray;
 
 /* FDSelect */
 struct FDSelect0 {
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+  }
+
   HBUINT8     fds[VAR];
+
+  DEFINE_SIZE_MIN (1);
 };
 
 struct FDSelect3_Range {
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) && (first < c->get_num_glyphs ())));
+  }
+
   HBUINT16    first;
   HBUINT8     fd;
+
+  DEFINE_SIZE_STATIC (3);
 };
 
 struct FDSelect3 {
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) && (nRanges > 0) &&
+                         (ranges[nRanges - 1].sanitize (c))));
+  }
+
   HBUINT16         nRanges;
   FDSelect3_Range  ranges[VAR];
   /* HBUINT16 sentinel */
+
+  DEFINE_SIZE_MIN (5);
 };
 
 struct FDSelect {
-  // XXX: need to sanitize at run time
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) && (format == 0 || format == 3) &&
+                          (format == 0)? u.format0.sanitize (c): u.format3.sanitize (c)));
+  }
+
   HBUINT8       format;
   union {
     FDSelect0   format0;
     FDSelect3   format3;
   } u;
+
+  DEFINE_SIZE_MIN (2);
 };
 
 inline float parse_bcd (const ByteStr& str, unsigned int& offset, float& v)
@@ -471,5 +508,5 @@ struct Interpreter {
 
 } /* namespace CFF */
 
-#endif /* HB_OT_CFF_COMMON_HH */
+#endif /* HB_OT_CFF_COMMON_PRIVATE_HH */
 
index 2f49591..5abfc78 100644 (file)
@@ -289,7 +289,6 @@ struct cff2
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
-                  version.sanitize (c) &&
                   likely (version.major == 2));
   }
 
@@ -297,17 +296,23 @@ struct cff2
   {
     inline void init (hb_face_t *face)
     {
-      this->blob = OT::Sanitizer<OT::cff2>().sanitize (face->reference_table (HB_OT_TAG_cff2));
+      hb_sanitize_context_t c;
+      this->blob = c.reference_table<cff2> (face);
       const OT::cff2 *cff2 = this->blob->as<OT::cff2> ();
 
       if (cff2 == &Null(OT::cff2))
       {
-        hb_blob_destroy (blob);
+        fini ();
         return;
       }
 
       { /* parse top dict */
         ByteStr topDictStr (cff2 + cff2->topDict, cff2->topDictSize);
+        if (unlikely (!topDictStr.sanitize (&c)))
+        {
+          fini ();
+          return;
+        }
         CFF2TopDict_Interpreter top_interp;
         top_interp.init ();
         top_interp.interpret (topDictStr, top);
@@ -319,20 +324,27 @@ struct cff2
       fdArray = &OT::StructAtOffset<FDArray>(cff2, top.FDArrayOffset);
       fdSelect = &OT::StructAtOffset<FDSelect>(cff2, top.FDSelectOffset);
       
-      // XXX: sanitize above?
-      if ((charStrings == &Null(CharStrings)) ||
-          (fdArray == &Null(FDArray)))
+      if (((varStore != &Null(VariationStore)) && unlikely (!varStore->sanitize (&c))) ||
+          ((charStrings == &Null(CharStrings)) || unlikely (!charStrings->sanitize (&c))) ||
+          ((fdArray == &Null(FDArray)) || unlikely (!fdArray->sanitize (&c))) ||
+          ((fdSelect == &Null(FDSelect)) || unlikely (!fdSelect->sanitize (&c))))
       {
-        hb_blob_destroy (blob);
+        fini ();
         return;
       }
 
       num_glyphs = charStrings->count;
+      if (num_glyphs != c.get_num_glyphs ())
+      {
+        fini ();
+        return;
+      }
     }
 
     inline void fini (void)
     {
       hb_blob_destroy (blob);
+      blob = nullptr;
     }
 
     inline bool get_extents (hb_codepoint_t glyph,
index 7ec1546..66681e9 100644 (file)
@@ -104,7 +104,7 @@ bool
 hb_subset_cff2 (hb_subset_plan_t *plan,
                 hb_blob_t       **cff2_prime /* OUT */)
 {
-  hb_blob_t *cff2_blob = OT::Sanitizer<OT::cff2>().sanitize (plan->source->reference_table (HB_OT_TAG_cff2));
+  hb_blob_t *cff2_blob = OT::hb_sanitize_context_t().reference_table<CFF::cff2> (plan->source);
   const char *cff2_data = hb_blob_get_data(cff2_blob, nullptr);
 
   OT::cff2::accelerator_t cff2;