diff --git a/gfx/cairo/cairo/src/cairo-truetype-subset.c b/gfx/cairo/cairo/src/cairo-truetype-subset.c --- a/gfx/cairo/cairo/src/cairo-truetype-subset.c +++ b/gfx/cairo/cairo/src/cairo-truetype-subset.c @@ -1446,23 +1446,32 @@ cleanup: */ #define MAX_FONT_NAME_LENGTH 127 static cairo_status_t find_name (tt_name_t *name, unsigned long size, int name_id, int platform, int encoding, int language, char **str_out) { tt_name_record_t *record; unsigned int i, len; + unsigned long max_records; char *str; char *p; cairo_bool_t has_tag; cairo_status_t status; str = NULL; - for (i = 0; i < MIN(be16_to_cpu (name->num_records), size / sizeof(name->records[0])); i++) { + /* records[] starts after the 6-byte tt_name_t header (format, + * num_records, strings_offset); only records lying entirely within the + * size-byte table may be read. */ + if (size < offsetof (tt_name_t, records)) { + *str_out = NULL; + return CAIRO_STATUS_SUCCESS; + } + max_records = (size - offsetof (tt_name_t, records)) / sizeof(name->records[0]); + for (i = 0; i < MIN(be16_to_cpu (name->num_records), max_records); i++) { record = &(name->records[i]); if (be16_to_cpu (record->name) == name_id && be16_to_cpu (record->platform) == platform && be16_to_cpu (record->encoding) == encoding && (language == -1 || be16_to_cpu (record->language) == language)) { len = be16_to_cpu (record->length); if (platform == 3 && len > MAX_FONT_NAME_LENGTH*2) /* UTF-16 name */