Subject: Re: bug#32201: 27.0.50; setenv should not change match-data

From: Noam Postavsky <[email-masked]>
Date: Wed, 18 Jul 2018 18:52:18 -0400

tags 32201 + patch
quit

John Shahid <[email-masked]> writes:
>
>     (add-hook 'buffer-list-update-hook
>               (lambda ()

>                          (setenv "GOPATH" gopath))))))

> The problem seems to happen when all of the suddent 'find-file' will
> start openning weird files.  For example, if I'm currently viewing
> "~/foo/bar.txt" and use 'C-x C-f' the default file name will be
> "~/foo/~jvshahid/foo/bar.txt".  After some debugging it turns out that
> the following will happen which cause the match-data to be corrupted:
>
> 1. find-file calls abbreviate-file-name
> 2. abbreviate-file-name calls (expand-file-name "~")
> 3. expand-file-name runs the buffer-list-update-hook (unknown why)
> 4. the hook will use setenv which messes up the match-data
> 5. abbreviate-file-name resumes and use the incorrect match-data and return an invalid path
>
> I don't know why '3' is happening.

buffer-list-update-hook gets called by get-buffer-create and
kill-buffer; it seems plausible that some file name handlers would use
make-temp-buffer which calls both of those.

Anyway, I don't think setenv should be changed, rather
abbreviate-file-name should save-match-data around the expand-file-name
call.  After all, today you happened to use setenv in a hook, tomorrow
someone will use another match-data modifying function.

Here's the patch (intended for emacs-26):

>From a0eec7f2e672804f3a7a30e55c821ba2dac213b7 Mon Sep 17 00:00:00 2001
From: Noam Postavsky <[email-masked]>
Date: Wed, 18 Jul 2018 18:45:47 -0400
Subject: [PATCH v1] Add save-match-data to abbreviate-file-name (Bug#32201)

* lisp/files.el (abbreviate-file-name): Save match-data around
expand-file-name; it is not guaranteed to preserve match-data, and may
well do so depending on what file handlers and hooks are in effect.
---
 lisp/files.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lisp/files.el b/lisp/files.el
index fb8c34bcae..4eb1560a20 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -1929,7 +1929,7 @@ abbreviate-file-name
 			 (save-match-data
 			   (string-match "^[a-zA-`]:/$" filename))))
                (equal (get 'abbreviated-home-dir 'home)
-                      (expand-file-name "~")))
+                      (save-match-data (expand-file-name "~"))))
 	  (setq filename
 		(concat "~"
 			(match-string 1 filename)
-- 
2.11.0