From: Michiharu Ariza Date: Tue, 11 Dec 2018 20:21:24 +0000 (-0800) Subject: [CFF] oss-fuzz issue 11690 ASSERT: substr.offset >= opStart (#1461) X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2941208f1eedabec2715b2a67d40f058df7eb5e6;p=platform%2Fupstream%2FlibHarfBuzzSharp.git [CFF] oss-fuzz issue 11690 ASSERT: substr.offset >= opStart (#1461) * fix oss-fuzz 11690: substr.offset >= opStart detect recursive subroutine call & handle as error * fix build failure * add minimized test case for oss-fuzz 11690 * removed asserts --- diff --git a/src/hb-cff-interp-common.hh b/src/hb-cff-interp-common.hh index effc081..6b81401 100644 --- a/src/hb-cff-interp-common.hh +++ b/src/hb-cff-interp-common.hh @@ -332,8 +332,10 @@ struct ByteStr inline bool sanitize (hb_sanitize_context_t *c) const { return str->sanitize (c, len); } inline const HBUINT8& operator [] (unsigned int i) const { - assert (str && (i < len)); - return (*str)[i]; + if (likely (str && (i < len))) + return (*str)[i]; + else + return Null(HBUINT8); } inline bool serialize (hb_serialize_context_t *c, const ByteStr &src) @@ -628,7 +630,6 @@ struct ParsedValues { VAL *val = values.push (); val->op = op; - assert (substr.offset >= opStart); val->str = ByteStr (substr.str, opStart, substr.offset - opStart); opStart = substr.offset; } @@ -637,7 +638,6 @@ struct ParsedValues { VAL *val = values.push (v); val->op = op; - assert (substr.offset >= opStart); val->str = ByteStr (substr.str, opStart, substr.offset - opStart); opStart = substr.offset; } @@ -707,7 +707,6 @@ struct InterpEnv inline void pop_n_args (unsigned int n) { - assert (n <= argStack.get_count ()); argStack.pop (n); } diff --git a/src/hb-subset-cff-common.hh b/src/hb-subset-cff-common.hh index cd29d4e..7f3a12f 100644 --- a/src/hb-subset-cff-common.hh +++ b/src/hb-subset-cff-common.hh @@ -526,11 +526,19 @@ struct SubrSubsetParam } template - inline void set_current_str (ENV &env) + inline void set_current_str (ENV &env, bool calling) { ParsedCStr *parsed_str = get_parsed_str_for_context (env.context); if (likely (parsed_str != nullptr)) - current_parsed_str = parsed_str; + { + /* If the called subroutine is parsed partially but not completely yet, + * it must be because we are calling it recursively. + * Handle it as an error. */ + if (unlikely (calling && !parsed_str->is_parsed () && (parsed_str->values.len > 0))) + env.set_error (); + else + current_parsed_str = parsed_str; + } else env.set_error (); } diff --git a/src/hb-subset-cff1.cc b/src/hb-subset-cff1.cc index 7c8b14c..0a29226 100644 --- a/src/hb-subset-cff1.cc +++ b/src/hb-subset-cff1.cc @@ -362,7 +362,7 @@ struct CFF1CSOpSet_SubrSubset : CFF1CSOpSetadd_op (op, env.substr); param.current_parsed_str->set_parsed (); env.returnFromSubr (); - param.set_current_str (env); + param.set_current_str (env, false); break; case OpCode_endchar: @@ -395,7 +395,7 @@ struct CFF1CSOpSet_SubrSubset : CFF1CSOpSetadd_call_op (op, substr, env.context.subr_num); hb_set_add (closure, env.context.subr_num); - param.set_current_str (env); + param.set_current_str (env, true); } private: diff --git a/src/hb-subset-cff2.cc b/src/hb-subset-cff2.cc index f7df404..84608c1 100644 --- a/src/hb-subset-cff2.cc +++ b/src/hb-subset-cff2.cc @@ -184,7 +184,7 @@ struct CFF2CSOpSet_SubrSubset : CFF2CSOpSetset_parsed (); env.returnFromSubr (); - param.set_current_str (env); + param.set_current_str (env, false); break; case OpCode_endchar: @@ -216,7 +216,7 @@ struct CFF2CSOpSet_SubrSubset : CFF2CSOpSetadd_call_op (op, substr, env.context.subr_num); hb_set_add (closure, env.context.subr_num); - param.set_current_str (env); + param.set_current_str (env, true); } private: diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5750420593442816 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5750420593442816 new file mode 100644 index 0000000..7f41718 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5750420593442816 differ