From 3419e7ea522462c47a5ab4389a879d8b7c14452b Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 20 Aug 2024 21:56:41 +0800 Subject: [PATCH] Correct Android failure to open an old CJK font * src/sfnt.c (sfnt_read_cmap_format_2): Properly compute subtable count, and append the empty table at position 0. (sfnt_lookup_glyph_2): Update commentary. --- src/sfnt.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) 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);