[subset] Check instruction offsets in glyph to ensure they are in bounds.

This commit is contained in:
Garret Rieger 2018-04-19 15:30:35 -07:00
parent 3c97614598
commit 4fa1c6705a
3 changed files with 47 additions and 2 deletions

View File

@ -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<HBUINT16> (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;
}

View File

@ -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();