[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master bf60338: Fix NS crash on invalid frame title string (bug#42904)
From: |
Mattias Engdegård |
Subject: |
master bf60338: Fix NS crash on invalid frame title string (bug#42904) |
Date: |
Thu, 20 Aug 2020 13:43:17 -0400 (EDT) |
branch: master
commit bf60338d6dd02b4d848229878c8e14182f6f861f
Author: Mattias Engdegård <mattiase@acm.org>
Commit: Mattias Engdegård <mattiase@acm.org>
Fix NS crash on invalid frame title string (bug#42904)
Instead of blindly assuming that all Emacs strings are valid UTF-8,
which they are not, use a more careful conversion going via UTF-16
which is what NSString uses internally. Unpaired surrogates will
still go through to the NSString objects, but the NS libs handle them
gracefully.
* src/nsterm.h (EmacsString): New category.
* src/nsfns.m (all_nonzero_ascii): New helper function.
([NSString stringWithLispString:]): New method.
(ns_set_name_internal): Use new conversion method.
---
src/nsfns.m | 65 +++++++++++++++++++++++++++++++++++++++++++++++-------------
src/nsterm.h | 5 +++++
2 files changed, 56 insertions(+), 14 deletions(-)
diff --git a/src/nsfns.m b/src/nsfns.m
index 628233e..5fca155 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -401,26 +401,15 @@ ns_set_icon_name (struct frame *f, Lisp_Object arg,
Lisp_Object oldval)
static void
ns_set_name_internal (struct frame *f, Lisp_Object name)
{
- Lisp_Object encoded_name, encoded_icon_name;
- NSString *str;
NSView *view = FRAME_NS_VIEW (f);
-
-
- encoded_name = ENCODE_UTF_8 (name);
-
- str = [NSString stringWithUTF8String: SSDATA (encoded_name)];
-
+ NSString *str = [NSString stringWithLispString: name];
/* Don't change the name if it's already NAME. */
if (! [[[view window] title] isEqualToString: str])
[[view window] setTitle: str];
- if (!STRINGP (f->icon_name))
- encoded_icon_name = encoded_name;
- else
- encoded_icon_name = ENCODE_UTF_8 (f->icon_name);
-
- str = [NSString stringWithUTF8String: SSDATA (encoded_icon_name)];
+ if (STRINGP (f->icon_name))
+ str = [NSString stringWithLispString: f->icon_name];
if ([[view window] miniwindowTitle]
&& ! [[[view window] miniwindowTitle] isEqualToString: str])
@@ -3031,6 +3020,54 @@ DEFUN ("ns-show-character-palette",
#endif
+/* Whether N bytes at STR are in the [0,127] range. */
+static bool
+all_nonzero_ascii (unsigned char *str, ptrdiff_t n)
+{
+ for (ptrdiff_t i = 0; i < n; i++)
+ if (str[i] < 1 || str[i] > 127)
+ return false;
+ return true;
+}
+
+@implementation NSString (EmacsString)
+/* Make an NSString from a Lisp string. */
++ (NSString *)stringWithLispString:(Lisp_Object)string
+{
+ /* Shortcut for the common case. */
+ if (all_nonzero_ascii (SDATA (string), SBYTES (string)))
+ return [NSString stringWithCString: SSDATA (string)
+ encoding: NSASCIIStringEncoding];
+ string = string_to_multibyte (string);
+
+ /* Now the string is multibyte; convert to UTF-16. */
+ unichar *chars = xmalloc (4 * SCHARS (string));
+ unichar *d = chars;
+ const unsigned char *s = SDATA (string);
+ const unsigned char *end = s + SBYTES (string);
+ while (s < end)
+ {
+ int c = string_char_advance (&s);
+ /* We pass unpaired surrogates through, because they are typically
+ handled fairly well by the NS libraries (displayed with distinct
+ glyphs etc). */
+ if (c <= 0xffff)
+ *d++ = c;
+ else if (c <= 0x10ffff)
+ {
+ *d++ = 0xd800 + (c & 0x3ff);
+ *d++ = 0xdc00 + ((c - 0x10000) >> 10);
+ }
+ else
+ *d++ = 0xfffd; /* Not valid for UTF-16. */
+ }
+ NSString *str = [NSString stringWithCharacters: chars
+ length: d - chars];
+ xfree (chars);
+ return str;
+}
+@end
+
/* ==========================================================================
Lisp interface declaration
diff --git a/src/nsterm.h b/src/nsterm.h
index a511fef..ab868ed 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -361,6 +361,11 @@ typedef id instancetype;
@end
+
+@interface NSString (EmacsString)
++ (NSString *)stringWithLispString:(Lisp_Object)string;
+@end
+
/* ==========================================================================
The Emacs application
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master bf60338: Fix NS crash on invalid frame title string (bug#42904),
Mattias Engdegård <=