From 28fcdb521922db56a30f75f7d3e656fcb8ef6bd7 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Mon, 28 Jun 2021 19:50:31 +0100 Subject: [PATCH] Fix crash in GNUstep font coverage check * src/nsfont.m (ns_charset_covers): Check coverage more accurately and don't automatically assume the buffer is 8192 bytes long. --- src/nsfont.m | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/nsfont.m b/src/nsfont.m index 06e10d52bea..5a9cdfebc01 100644 --- a/src/nsfont.m +++ b/src/nsfont.m @@ -277,30 +277,36 @@ ns_ascii_average_width (NSFont *sfont) /* Return whether set1 covers set2 to a reasonable extent given by pct. - We check, out of each 16 Unicode char range containing chars in set2, - whether at least one character is present in set1. - This must be true for pct of the pairs to consider it covering. */ + + The GNUstep bitmap representation doesn't match Apple's + description. It appears to be a single block of bytes, not broken + up into planes, where the last byte contains the highest character + the character set supports. */ static BOOL ns_charset_covers(NSCharacterSet *set1, NSCharacterSet *set2, float pct) { - const unsigned short *bytes1 = [[set1 bitmapRepresentation] bytes]; - const unsigned short *bytes2 = [[set2 bitmapRepresentation] bytes]; - int i, off = 0, tot = 0; + NSData *font = [set1 bitmapRepresentation]; + NSData *script = [set2 bitmapRepresentation]; - /* Work around what appears to be a GNUstep bug. - See . */ - if (! (bytes1 && bytes2)) - return NO; + uint8_t *fontPlane = (uint8_t *)[font bytes]; + uint8_t *scriptPlane = (uint8_t *)[script bytes]; - for (i=0; i<4096; i++, bytes1++, bytes2++) - if (*bytes2) - { - tot++; - if (*bytes1 == 0) // *bytes1 & *bytes2 != *bytes2 - off++; - } - // fprintf(stderr, "off = %d\ttot = %d\n", off,tot); - return (float)off / tot < 1.0F - pct; + int covered = 0, total = 0; + + for (ptrdiff_t b = 0 ; b < [script length] ; b++) + for (int i = 0 ; i < 8 ; i++) + { + if (*(scriptPlane + b) & (1 << i)) + { + total++; + + if (b < [font length] + && *(fontPlane + b) & (1 << i)) + covered++; + } + } + + return (float)covered / total >= 1.0F - pct; } -- 2.39.2