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