[subset] Add a fix for segfault in hmtx/vmtx subsetting code.

This commit is contained in:
Garret Rieger 2018-03-19 18:39:22 -07:00
parent 31281d6a17
commit 1a94804d35
2 changed files with 13 additions and 3 deletions

View File

@ -118,6 +118,8 @@ struct hmtxvmtx
LongMetric * old_metrics = (LongMetric *) source_table; LongMetric * old_metrics = (LongMetric *) source_table;
FWORD *lsbs = (FWORD *) (old_metrics + _mtx.num_advances); FWORD *lsbs = (FWORD *) (old_metrics + _mtx.num_advances);
char * dest_pos = (char *) dest; char * dest_pos = (char *) dest;
bool failed = false;
for (unsigned int i = 0; i < gids.len; i++) for (unsigned int i = 0; i < gids.len; i++)
{ {
/* the last metric or the one for gids[i] */ /* the last metric or the one for gids[i] */
@ -138,7 +140,14 @@ struct hmtxvmtx
} }
else else
{ {
FWORD src_lsb = *(lsbs + gids[i] - _mtx.num_advances); if (gids[i] >= _mtx.num_metrics)
{
DEBUG_MSG(SUBSET, nullptr, "gid %d is >= number of source metrics %d",
gids[i], _mtx.num_metrics);
failed = true;
break;
}
FWORD src_lsb = *(lsbs + gids[i] - _mtx.num_advances);
if (i < num_advances) if (i < num_advances)
{ {
/* dest needs a full LongMetric */ /* dest needs a full LongMetric */
@ -157,7 +166,7 @@ struct hmtxvmtx
_mtx.fini (); _mtx.fini ();
// Amend header num hmetrics // Amend header num hmetrics
if (unlikely (!subset_update_header (plan, num_advances))) if (failed || unlikely (!subset_update_header (plan, num_advances)))
{ {
free (dest); free (dest);
return false; return false;

View File

@ -163,7 +163,8 @@ test_subset_invalid_hmtx (void)
hb_subset_profile_t *profile = hb_subset_profile_create(); hb_subset_profile_t *profile = hb_subset_profile_create();
hb_face_t *subset = hb_subset (face, profile, input); hb_face_t *subset = hb_subset (face, profile, input);
g_assert (!subset); g_assert (subset);
g_assert (subset == hb_face_get_empty ());
hb_subset_input_destroy (input); hb_subset_input_destroy (input);
hb_subset_profile_destroy (profile); hb_subset_profile_destroy (profile);