diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index 3e8b5eb4a..85cb3a379 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -433,9 +433,23 @@ struct glyf else { unsigned int instruction_length_offset = start_offset + GlyphHeader::static_size + 2 * num_contours; + if (unlikely (instruction_length_offset + 2 > end_offset)) + { + DEBUG_MSG(SUBSET, nullptr, "Glyph size is too short, missing field instructionLength."); + return false; + } + const HBUINT16 &instruction_length = StructAtOffset (glyf_table, instruction_length_offset); - *instruction_start = instruction_length_offset + 2; - *instruction_end = *instruction_start + (uint16_t) instruction_length; + unsigned int start = instruction_length_offset + 2; + unsigned int end = start + (uint16_t) instruction_length; + if (unlikely (end > end_offset)) // Out of bounds of the current glyph + { + DEBUG_MSG(SUBSET, nullptr, "The instructions array overruns the glyph's boundaries."); + return false; + } + + *instruction_start = start; + *instruction_end = end; } return true; } diff --git a/test/api/fonts/oom-ccc61c92d589f895174cdef6ff2e3b20e9999a1a b/test/api/fonts/oom-ccc61c92d589f895174cdef6ff2e3b20e9999a1a new file mode 100644 index 000000000..1af243ebc Binary files /dev/null and b/test/api/fonts/oom-ccc61c92d589f895174cdef6ff2e3b20e9999a1a differ diff --git a/test/api/test-subset-glyf.c b/test/api/test-subset-glyf.c index e72086a33..4ea2d8910 100644 --- a/test/api/test-subset-glyf.c +++ b/test/api/test-subset-glyf.c @@ -171,6 +171,36 @@ test_subset_glyf_strip_hints_composite (void) hb_face_destroy (face_components); } +static void +test_subset_glyf_strip_hints_invalid (void) +{ + hb_face_t *face = hb_subset_test_open_font ("fonts/oom-ccc61c92d589f895174cdef6ff2e3b20e9999a1a"); + + hb_set_t *codepoints = hb_set_create(); + const hb_codepoint_t text[] = + { + 'A', 'B', 'C', 'D', 'E', 'X', 'Y', 'Z', '1', '2', + '3', '@', '_', '%', '&', ')', '*', '$', '!' + }; + int i; + for (i = 0; i < sizeof (text) / sizeof (hb_codepoint_t); i++) + { + hb_set_add (codepoints, text[i]); + // hb_set_add (codepoints_drop_hints, text[i]); + } + + hb_subset_input_t *input = hb_subset_test_create_input (codepoints); + *hb_subset_input_drop_hints(input) = true; + hb_set_destroy (codepoints); + + hb_face_t *face_subset = hb_subset_test_create_subset (face, input); + g_assert (face_subset); + g_assert (face_subset == hb_face_get_empty ()); + + hb_face_destroy (face_subset); + hb_face_destroy (face); +} + // TODO(grieger): test for long loca generation. int @@ -182,6 +212,7 @@ main (int argc, char **argv) hb_test_add (test_subset_glyf); hb_test_add (test_subset_glyf_strip_hints_simple); hb_test_add (test_subset_glyf_strip_hints_composite); + hb_test_add (test_subset_glyf_strip_hints_invalid); hb_test_add (test_subset_glyf_with_components); return hb_test_run();