]> git.ipfire.org Git - thirdparty/vim.git/commit
patch 9.1.2138: win_execute() and 'autochdir' can corrupt buffer name v9.1.2138
authorIngo Karkat <swdev@ingo-karkat.de>
Sat, 7 Feb 2026 10:41:32 +0000 (10:41 +0000)
committerChristian Brabandt <cb@256bit.org>
Sat, 7 Feb 2026 10:41:32 +0000 (10:41 +0000)
commitabb4d740338e667991656e3ca575e623aba7bd2a
treecc7aa399ecfb7a787974f4ce57089542ce45c9c2
parenta24cb278bdf3ef618e46c1c88c9d02c838ab6065
patch 9.1.2138: win_execute() and 'autochdir' can corrupt buffer name

Problem:  With 'autochdir' win_execute() can corrupt the buffer name,
          causing :write to use wrong path.
Solution: Save and restore b_fname when 'autochdir' is active
          (Ingo Karkat).

This is caused by a bad interaction of the 'autochdir' behavior,
overriding of the current directory via :lchdir, and the temporary
window switching done by win_execute(), manifesting when e.g. a custom
completion inspects other buffers:
1. In the initial state after the :lcd .. we have curbuf->b_fname =
   "Xsubdir/file".
2. do_autochdir() is invoked, temporarily undoing the :lcd .., changing
   back into the Xsubdir/ subdirectory.
3. win_execute() switches windows, triggering win_enter_ext() →
   win_fix_current_dir() → shorten_fnames(TRUE)
4. shorten_fnames() processes *all* buffers
5. shorten_buf_fname() makes the filename relative to the current
   (wrong) directory; b_fname becomes "file" instead of "Xsubdir/file"
6. Directory restoration correctly restores working directory via
   mch_chdir() (skipping a second do_autochdir() invocation because
   apply_acd is FALSE), but b_fname remains corrupted, with the
   "Xsubdir/" part missing.
7. expand("%:p") (and commands like :write) continue to use the
   corrupted filename, resolving to a wrong path that's missing the
   "Xsubdir/" part.

To fix the problem the short filename is saved if its in effect (i.e.
pointed to by curbuf->b_fname) and 'autochdir' happened. It's then
restored in case of a local cwd override. The conditions limit this
workaround to when 'autochdir' is active *and* overridden by a :lchdir.

closes: #19343

Co-authored-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Ingo Karkat <swdev@ingo-karkat.de>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/doc/version9.txt
src/evalwindow.c
src/testdir/test_cd.vim
src/version.c