Merge pull request #1449 from harfbuzz/cff-fixcharset

[CFF] fix for oss-fuzz 11657: Charset overrun
diff --git a/src/hb-cff-interp-cs-common.hh b/src/hb-cff-interp-cs-common.hh
index 85546fc..067dc1c 100644
--- a/src/hb-cff-interp-cs-common.hh
+++ b/src/hb-cff-interp-cs-common.hh
@@ -65,7 +65,7 @@
   inline void init (const SUBRS &subrs_)
   {
     subrs = &subrs_;
-    unsigned int  nSubrs = subrs_.count;
+    unsigned int  nSubrs = get_count ();
     if (nSubrs < 1240)
       bias = 107;
     else if (nSubrs < 33900)
@@ -76,8 +76,20 @@
 
   inline void fini (void) {}
 
-  const SUBRS   *subrs;
+  inline unsigned int get_count (void) const { return (subrs == nullptr)? 0: subrs->count; }
+  inline unsigned int get_bias (void) const { return bias; }
+
+  inline ByteStr operator [] (unsigned int index) const
+  {
+    if (unlikely ((subrs == nullptr) || index >= subrs->count))
+      return Null(ByteStr);
+    else
+      return (*subrs)[index];
+  }
+
+  protected:
   unsigned int  bias;
+  const SUBRS   *subrs;
 };
 
 struct Point
@@ -137,8 +149,8 @@
   inline bool popSubrNum (const BiasedSubrs<SUBRS>& biasedSubrs, unsigned int &subr_num)
   {
     int n = SUPER::argStack.pop_int ();
-    n += biasedSubrs.bias;
-    if (unlikely ((n < 0) || ((unsigned int)n >= biasedSubrs.subrs->count)))
+    n += biasedSubrs.get_bias ();
+    if (unlikely ((n < 0) || ((unsigned int)n >= biasedSubrs.get_count ())))
       return false;
 
     subr_num = (unsigned int)n;
@@ -158,7 +170,7 @@
     context.substr = SUPER::substr;
     callStack.push (context);
 
-    context.init ( (*biasedSubrs.subrs)[subr_num], type, subr_num);
+    context.init ( biasedSubrs[subr_num], type, subr_num);
     SUPER::substr = context.substr;
   }
 
diff --git a/src/hb-ot-cff-common.hh b/src/hb-ot-cff-common.hh
index e824dae..2c16500 100644
--- a/src/hb-ot-cff-common.hh
+++ b/src/hb-ot-cff-common.hh
@@ -208,7 +208,7 @@
   inline unsigned int data_size (void) const
   { return HBINT8::static_size; }
 
-  ByteStr operator [] (unsigned int index) const
+  inline ByteStr operator [] (unsigned int index) const
   {
     if (likely (index < count))
       return ByteStr (data_base () + offset_at (index) - 1, offset_at (index + 1) - offset_at (index));
diff --git a/src/hb-ot-cff1-table.hh b/src/hb-ot-cff1-table.hh
index aac66d8..39da8fa 100644
--- a/src/hb-ot-cff1-table.hh
+++ b/src/hb-ot-cff1-table.hh
@@ -1094,6 +1094,7 @@
 	  CFF1FontDict_Interpreter font_interp;
 	  font_interp.env.init (fontDictStr);
 	  font = fontDicts.push ();
+	  if (unlikely (font == &Crap(CFF1FontDictValues))) { fini (); return; }
 	  font->init ();
 	  if (unlikely (!font_interp.interpret (*font))) { fini (); return; }
 	  PRIVDICTVAL  *priv = &privateDicts[i];
@@ -1133,7 +1134,7 @@
     {
       sc.end_processing ();
       topDict.fini ();
-      fontDicts.fini ();
+      fontDicts.fini_deep ();
       privateDicts.fini_deep ();
       hb_blob_destroy (blob);
       blob = nullptr;
diff --git a/src/hb-ot-cff2-table.hh b/src/hb-ot-cff2-table.hh
index 3c4191c..178acf0 100644
--- a/src/hb-ot-cff2-table.hh
+++ b/src/hb-ot-cff2-table.hh
@@ -486,6 +486,7 @@
 	CFF2FontDict_Interpreter font_interp;
 	font_interp.env.init (fontDictStr);
 	font = fontDicts.push ();
+	if (unlikely (font == &Crap(CFF2FontDictValues))) { fini (); return; }
 	font->init ();
 	if (unlikely (!font_interp.interpret (*font))) { fini (); return; }
 
@@ -506,7 +507,7 @@
     inline void fini (void)
     {
       sc.end_processing ();
-      fontDicts.fini ();
+      fontDicts.fini_deep ();
       privateDicts.fini_deep ();
       hb_blob_destroy (blob);
       blob = nullptr;
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5175735354916864 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5175735354916864
new file mode 100644
index 0000000..72fdfc6
--- /dev/null
+++ b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5175735354916864
Binary files differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5672913680728064 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5672913680728064
new file mode 100644
index 0000000..fdb5bff
--- /dev/null
+++ b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5672913680728064
Binary files differ