Subject: Re: bug#48902: 28.0.50; Directory names containing apostrophes and backticks cause problems

From: Alan Third <[email-masked]>
Date: Tue, 8 Jun 2021 20:10:04 +0100

On Tue, Jun 08, 2021 at 07:45:22PM +0200, Mattias Engdegård wrote:
> 8 juni 2021 kl. 14.14 skrev Lars Ingebrigtsen <[email-masked]>:
> 
> >> It's always possible that stringWithLispString isn't doing the right
> >> thing. It's implemented at nsfns.m:3026. I know almost nothing about
> >> UTF8/UTF16 so while it looks like it's doing the right thing to me, I
> >> could be entirely wrong.
> > 
> > Right -- and that was written by Mattias, so I've added him to the CCs.
> 
> Thank you, but stringWithLispString: is actually fine, unless you
> count its inability to produce useful results from wrong input!

In my defence it wasn't entirely clear to me that a lisp string
returned from ENCODE_FILE was incompatible with stringWithLispString. ;)

> The image code seems to be quite confused with respect to whether
> the file names being passed around are in encoded form. Until
> recently it seems to have worked by pure chance since as long as the
> file name encoding is UTF-8 and the low-level code accesses the raw
> string data we do get the same result, but at least since
> 747a923b9a35 that's no longer the case.

Hmm, and as you point out we use "file" further down and it may or may
not be encoded, but will probably have the same contents as found,
which we know is encoded. Plus it's setting the "name" field in the
image, which we probably want to keep as uniform as possible for
caching purposes but is otherwise irrelevant.

I think the attached should solve this.
-- 
Alan Third
>From c2902846c57c55576b1612bf11afaf240994ca70 Mon Sep 17 00:00:00 2001
From: Alan Third <[email-masked]>
Date: Tue, 8 Jun 2021 20:08:34 +0100
Subject: [PATCH] Fix image filename encoding issues in NS port (bug#48902)

* src/nsfns.m ([NSString stringWithLispString:]): Clarify usage in comment.
* src/nsimage.m ([EmacsImage allocInitFromFile:]): Clarify that the
filename is UTF-8 encoded and handle it correctly.
---
 src/nsfns.m   |  3 ++-
 src/nsimage.m | 11 +++++------
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/nsfns.m b/src/nsfns.m
index d14f7b51ea..98801d8526 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -3024,7 +3024,8 @@ - (NSString *)panel: (id)sender userEnteredFilename: (NSString *)filename
 }
 
 @implementation NSString (EmacsString)
-/* Make an NSString from a Lisp string.  */
+/* Make an NSString from a Lisp string.  STRING must not be in an
+   encoded form (e.g. UTF-8).  */
 + (NSString *)stringWithLispString:(Lisp_Object)string
 {
   /* Shortcut for the common case.  */
diff --git a/src/nsimage.m b/src/nsimage.m
index fa81a41a51..b0bd52111b 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -252,17 +252,16 @@ @implementation EmacsImage
 + (instancetype)allocInitFromFile: (Lisp_Object)file
 {
   NSImageRep *imgRep;
-  Lisp_Object found;
+  Lisp_Object utf8_filename;
   EmacsImage *image;
 
   /* Search bitmap-file-path for the file, if appropriate.  */
-  found = image_find_image_file (file);
-  if (!STRINGP (found))
+  utf8_filename = image_find_image_file (file);
+  if (!STRINGP (utf8_filename))
     return nil;
-  found = ENCODE_FILE (found);
 
   image = [[EmacsImage alloc] initByReferencingFile:
-                     [NSString stringWithLispString: found]];
+                     [NSString stringWithUTF8String: SSDATA (utf8_filename)]];
 
   image->bmRep = nil;
 #ifdef NS_IMPL_COCOA
@@ -278,7 +277,7 @@ + (instancetype)allocInitFromFile: (Lisp_Object)file
 
   [image setSize: NSMakeSize([imgRep pixelsWide], [imgRep pixelsHigh])];
 
-  [image setName: [NSString stringWithLispString: file]];
+  [image setName: [NSString stringWithUTF8String: SSDATA (utf8_filename)]];
 
   return image;
 }
-- 
2.30.2