diff --git a/src/sfnt.c b/src/sfnt.c index 1ed492b7506..02b8a33041c 100644 --- a/src/sfnt.c +++ b/src/sfnt.c @@ -383,15 +383,18 @@ sfnt_read_cmap_format_2 (int fd, for (i = 0; i < 256; ++i) { + /* Values in sub_header_keys are actually offsets from the end of + that array. Since the language of the spec is such as to imply + that they must be divisible by eight, divide them by the + same. */ sfnt_swap16 (&format2->sub_header_keys[i]); if (format2->sub_header_keys[i] > nsub) - nsub = format2->sub_header_keys[i]; + nsub = format2->sub_header_keys[i] / 8; } - if (!nsub) - /* If there are no subheaders, then things are finished. */ - return format2; + /* There always exists a subheader at index zero. */ + nsub ++; /* Otherwise, read the rest of the variable length data to the end of format2. */ @@ -1108,9 +1111,11 @@ sfnt_lookup_glyph_2 (sfnt_char character, && j <= ((int) subheader->first_code + (int) subheader->entry_count)) { - /* id_range_offset is actually the number of bytes past - itself containing the uint16_t ``slice''. It is possibly - unaligned. */ + /* id_range_offset is actually the number of bytes past itself + containing the uint16_t ``slice''. Whether this may be + unaligned is not stated in the specification, but I doubt + it, for that would render values meaningless if the array + were byte swapped when read. */ slice = (unsigned char *) &subheader->id_range_offset; slice += subheader->id_range_offset; slice += (j - subheader->first_code) * sizeof (uint16_t);