aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Third2021-06-28 19:50:31 +0100
committerAlan Third2021-07-04 11:36:32 +0100
commit28fcdb521922db56a30f75f7d3e656fcb8ef6bd7 (patch)
tree4edce7a199ee210f6635f8660649a5cea670742c
parent0382aa114844c275467f62474497dd294688c52c (diff)
downloademacs-28fcdb521922db56a30f75f7d3e656fcb8ef6bd7.tar.gz
emacs-28fcdb521922db56a30f75f7d3e656fcb8ef6bd7.zip
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.
-rw-r--r--src/nsfont.m44
1 files 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)
277 277
278 278
279/* Return whether set1 covers set2 to a reasonable extent given by pct. 279/* Return whether set1 covers set2 to a reasonable extent given by pct.
280 We check, out of each 16 Unicode char range containing chars in set2, 280
281 whether at least one character is present in set1. 281 The GNUstep bitmap representation doesn't match Apple's
282 This must be true for pct of the pairs to consider it covering. */ 282 description. It appears to be a single block of bytes, not broken
283 up into planes, where the last byte contains the highest character
284 the character set supports. */
283static BOOL 285static BOOL
284ns_charset_covers(NSCharacterSet *set1, NSCharacterSet *set2, float pct) 286ns_charset_covers(NSCharacterSet *set1, NSCharacterSet *set2, float pct)
285{ 287{
286 const unsigned short *bytes1 = [[set1 bitmapRepresentation] bytes]; 288 NSData *font = [set1 bitmapRepresentation];
287 const unsigned short *bytes2 = [[set2 bitmapRepresentation] bytes]; 289 NSData *script = [set2 bitmapRepresentation];
288 int i, off = 0, tot = 0;
289 290
290 /* Work around what appears to be a GNUstep bug. 291 uint8_t *fontPlane = (uint8_t *)[font bytes];
291 See <https://bugs.gnu.org/11853>. */ 292 uint8_t *scriptPlane = (uint8_t *)[script bytes];
292 if (! (bytes1 && bytes2))
293 return NO;
294 293
295 for (i=0; i<4096; i++, bytes1++, bytes2++) 294 int covered = 0, total = 0;
296 if (*bytes2) 295
297 { 296 for (ptrdiff_t b = 0 ; b < [script length] ; b++)
298 tot++; 297 for (int i = 0 ; i < 8 ; i++)
299 if (*bytes1 == 0) // *bytes1 & *bytes2 != *bytes2 298 {
300 off++; 299 if (*(scriptPlane + b) & (1 << i))
301 } 300 {
302 // fprintf(stderr, "off = %d\ttot = %d\n", off,tot); 301 total++;
303 return (float)off / tot < 1.0F - pct; 302
303 if (b < [font length]
304 && *(fontPlane + b) & (1 << i))
305 covered++;
306 }
307 }
308
309 return (float)covered / total >= 1.0F - pct;
304} 310}
305 311
306 312