[subset] Check instruction offsets in glyph to ensure they are in bounds.
This commit is contained in:
parent
3c97614598
commit
4fa1c6705a
|
@ -433,9 +433,23 @@ struct glyf
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int instruction_length_offset = start_offset + GlyphHeader::static_size + 2 * num_contours;
|
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);
|
const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (glyf_table, instruction_length_offset);
|
||||||
*instruction_start = instruction_length_offset + 2;
|
unsigned int start = instruction_length_offset + 2;
|
||||||
*instruction_end = *instruction_start + (uint16_t) instruction_length;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -171,6 +171,36 @@ test_subset_glyf_strip_hints_composite (void)
|
||||||
hb_face_destroy (face_components);
|
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.
|
// TODO(grieger): test for long loca generation.
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -182,6 +212,7 @@ main (int argc, char **argv)
|
||||||
hb_test_add (test_subset_glyf);
|
hb_test_add (test_subset_glyf);
|
||||||
hb_test_add (test_subset_glyf_strip_hints_simple);
|
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_composite);
|
||||||
|
hb_test_add (test_subset_glyf_strip_hints_invalid);
|
||||||
hb_test_add (test_subset_glyf_with_components);
|
hb_test_add (test_subset_glyf_with_components);
|
||||||
|
|
||||||
return hb_test_run();
|
return hb_test_run();
|
||||||
|
|
Loading…
Reference in New Issue