GNU bug report logs - #78777
30.1; insert-file-contents should not set buffer-file-name to nil

Previous Next

Package: emacs;

Reported by: Jimmy Yuen Ho Wong <wyuenho <at> gmail.com>

Date: Thu, 12 Jun 2025 16:59:01 UTC

Severity: normal

Found in version 30.1

Full log


Message #11 received at 78777 <at> debbugs.gnu.org (full text, mbox):

From: Jimmy Yuen Ho Wong <wyuenho <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 78777 <at> debbugs.gnu.org
Subject: Re: bug#78777: 30.1; insert-file-contents should not set
 buffer-file-name to nil
Date: Thu, 12 Jun 2025 20:34:30 +0100
[Message part 1 (text/plain, inline)]
On Thu, Jun 12, 2025 at 7:19 PM Eli Zaretskii <eliz <at> gnu.org> wrote:

> > From: Jimmy Yuen Ho Wong <wyuenho <at> gmail.com>
> > Date: Thu, 12 Jun 2025 17:58:34 +0100
> >
> >
> > When investigating https://github.com/emacs-lsp/lsp-mode/issues/4782 and
> > https://github.com/purcell/emacs-reformatter/issues/63, I've discovered
> > the following bug in insert-file-contents.
> >
> > Reproduction:
> >
> > 1. echo "hello world" > ~/test.txt
> > 2. emacs -q ~/test.txt
> > 3. M-x eval-expression RET (add-hook 'after-change-functions (lambda
> (&rest _) (message "buffer-file-name: %s, current-buffer: %s"
> (buffer-file-name) (current-buffer))) nil t) RET
> > 4. Type something into the buffer
> > 5. M-x eval-expression RET (insert-file-contents (buffer-file-name) nil
> nil nil t) RET
> > 6. Switch to the *Messages* buffer and observe the buffer file name is
> nil.
> >
> > Expectation:
> >
> > insert-file-contents should not set buffer-file-name to nil
>
> I don't think it does.  (buffer-file-name) returns nil when the call
> is evaluated in the minibuffer, and I thin that's what you see.  After
> performing the above recipe the buffer-filename of the buffer that
> visits test.txt remains to be "test.txt", at least in my testing.  So
> the only evidence that it's set to nil are the messages logged in
> *Messages*, and they are about a different buffer.
>

When a lisp expression is evaluated in the minibuffer, the current buffer
is the file buffer, not the minibuffer. You can easily verify this with M-x
eval-expression RET (current-buffer)  RET.

The crux of the matter is the lambda added to after-change-function.
`insert-file-contents` calls `signals_after_change` (fileio.c line 5007 on
master), which will run the after-change-functions. It is at this moment
the buffer-file-name is nil.

In addition, the following will NOT result in insert-file-contents
temporarily setting the buffer-file-name of the current buffer to nil:

(let ((coding-system-for-read 'no-conversion)
      (coding-system-for-write 'no-conversion))
  (insert-file-contents (buffer-file-name) nil nil nil t))

Which suggests some of the code conversion logic in the C function is
erroneously setting the current buffer's file-name to nil, and then running
the after-change-functions before resetting it.
[Message part 2 (text/html, inline)]

This bug report was last modified today.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.