diff --git a/src/hb-subset-cff-common.hh b/src/hb-subset-cff-common.hh index 340089283..422b20b8d 100644 --- a/src/hb-subset-cff-common.hh +++ b/src/hb-subset-cff-common.hh @@ -110,7 +110,11 @@ struct str_encoder_t void copy_str (const byte_str_t &str) { unsigned int offset = buff.length; - buff.resize (offset + str.length); + if (unlikely (!buff.resize (offset + str.length))) + { + set_error (); + return; + } if (unlikely (buff.length < offset + str.length)) { set_error (); @@ -412,7 +416,8 @@ struct parsed_cs_str_vec_t : hb_vector_t void init (unsigned int len_ = 0) { SUPER::init (); - resize (len_); + if (unlikely (!resize (len_))) + return; for (unsigned int i = 0; i < length; i++) (*this)[i].init (); } @@ -528,11 +533,16 @@ struct subr_remaps_t void init (unsigned int fdCount) { - local_remaps.resize (fdCount); + if (unlikely (!local_remaps.resize (fdCount))) return; for (unsigned int i = 0; i < fdCount; i++) local_remaps[i].init (); } + bool in_error() + { + return local_remaps.in_error (); + } + void create (subr_closures_t& closures) { global_remap.create (closures.global_closure); @@ -591,10 +601,19 @@ struct subr_subsetter_t parsed_charstrings.init (plan->num_output_glyphs ()); parsed_global_subrs.init (acc.globalSubrs->count); - parsed_local_subrs.resize (acc.fdCount); + + if (unlikely (remaps.in_error() + || parsed_charstrings.in_error () + || parsed_global_subrs.in_error ())) { + return false; + } + + if (unlikely (!parsed_local_subrs.resize (acc.fdCount))) return false; + for (unsigned int i = 0; i < acc.fdCount; i++) { parsed_local_subrs[i].init (acc.privateDicts[i].localSubrs->count); + if (unlikely (parsed_local_subrs[i].in_error ())) return false; } if (unlikely (!closures.valid)) return false; diff --git a/src/hb-subset-cff1.cc b/src/hb-subset-cff1.cc index f16b2533a..df322f845 100644 --- a/src/hb-subset-cff1.cc +++ b/src/hb-subset-cff1.cc @@ -406,7 +406,12 @@ struct cff_subset_plan { hb_codepoint_t code, last_code = CFF_UNDEF_CODE; hb_vector_t supp_codes; - subset_enc_code_ranges.resize (0); + if (unlikely (!subset_enc_code_ranges.resize (0))) + { + plan->check_success (false); + return; + } + supp_size = 0; supp_codes.init (); @@ -465,7 +470,12 @@ struct cff_subset_plan { unsigned int size0, size_ranges; hb_codepoint_t sid, last_sid = CFF_UNDEF_CODE; - subset_charset_ranges.resize (0); + if (unlikely (!subset_charset_ranges.resize (0))) + { + plan->check_success (false); + return; + } + unsigned int glyph; for (glyph = 1; glyph < plan->num_output_glyphs (); glyph++) { diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh index 5abd84fb1..e9f603dd1 100644 --- a/src/hb-subset-plan.hh +++ b/src/hb-subset-plan.hh @@ -92,6 +92,12 @@ struct hb_subset_plan_t bool in_error () const { return !successful; } + bool check_success(bool success) + { + successful = (successful && success); + return successful; + } + /* * The set of input glyph ids which will be retained in the subset. * Does NOT include ids kept due to retain_gids. You probably want to use diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5707809174585344 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5707809174585344 new file mode 100644 index 000000000..fba50e50e Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5707809174585344 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5708623339323392 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5708623339323392 new file mode 100644 index 000000000..4356547dd Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5708623339323392 differ