patch 9.2.0893: MS-Windows: "*.vim" also matches files with a longer extension
Commit:
https://github.com/vim/vim/commit/8e5d1761ce5d3a5af565d1828f53fa56687bc3c1
Author: Hirohito Higashi <
h.eas...@gmail.com>
Date: Sat Aug 1 13:47:20 2026 +0000
patch 9.2.0893: MS-Windows: "*.vim" also matches files with a longer extension
Problem: On MS-Windows a pattern like "path/*.vim" also matches files such
as "foo.vim9", because the 8.3 short name "FOO~1.VIM" is used for
matching as well. These files are then sourced.
Solution: Only match against the short name when the pattern contains a '~'
(Hirohito Higashi).
closes: #20899
Co-Authored-By: Claude Opus 5 (1M context) <
nor...@anthropic.com>
Signed-off-by: Hirohito Higashi <
h.eas...@gmail.com>
Signed-off-by: Christian Brabandt <
c...@256bit.org>
diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt
index 4789b8c3b..3b2f65a9c 100644
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -44,10 +44,6 @@ calling frame_new_height() and frame_new_width(), especially w_skipcol.
With 'splitkeep' "screen" the scroll position is lost when splitting and
closing a window, win_fix_cursor() moves the cursor to another line.
-Check places that source "path/*.vim" to not match other extensions, e.g.
-.vim9, on MS-Windows (short file name match, gets expanded to long file name).
-E.g. for startup files, plugins, packs, etc.
-
When a help item can't be found, then open 'helpfile'. Search for the tag in
that file and gtive E149 only when not found. Helps for a tiny Vim installed
without all the help files.
diff --git a/src/filepath.c b/src/filepath.c
index e70b9c300..388ce7af1 100644
--- a/src/filepath.c
+++ b/src/filepath.c
@@ -3578,6 +3578,7 @@ dos_expandpath(
char_u *matchname;
int ok;
char_u *p_alt;
+ int use_short_name;
// Expanding "**" may take a long time, check for CTRL-C.
if (stardepth > 0)
@@ -3672,6 +3673,10 @@ dos_expandpath(
// remember the pattern or file name being looked for
matchname = vim_strsave(s);
+ // Only match against the alternate (8.3) file name when the pattern looks
+ // like a short name, it contains a '~'.
+ use_short_name = vim_strchr(s, '~') != NULL;
+
len = (size_t)(s - buf);
// If "**" is by itself, this is the first time we encounter it and more
// is following then find matches without any directory.
@@ -3701,7 +3706,8 @@ dos_expandpath(
// Do not use the alternate filename when the file name ends in '~',
// because it picks up backup files: short name for "foo.vim~" is
// "foo~1.vim", which matches "*.vim".
- if (*wfb.cAlternateFileName == NUL || p[STRLEN(p) - 1] == '~')
+ if (!use_short_name || *wfb.cAlternateFileName == NUL
+ || p[STRLEN(p) - 1] == '~')
p_alt = NULL;
else
p_alt = utf16_to_enc(wfb.cAlternateFileName, NULL);
diff --git a/src/testdir/test_shortpathname.vim b/src/testdir/test_shortpathname.vim
index a1d9d9816..7bd72ebf7 100644
--- a/src/testdir/test_shortpathname.vim
+++ b/src/testdir/test_shortpathname.vim
@@ -121,4 +121,26 @@ func Test_ColonEight_then_tail()
call assert_equal(fnamemodify(sfile, ':r'), fnamemodify(file, ':p:8:r'))
endfunc
+" A pattern must not match the short name of a file with a longer extension:
+" the short name of "foo.vim9" is "FOO~1.VIM", which matches "*.vim".
+func Test_glob_short_name_extension()
+ let dir = 'c:/Xtest_glob8'
+ call s:SetupDir(dir)
+ call mkdir(dir, 'D')
+
+ let file = dir . '/foo.vim9'
+ call writefile([], file, 'D')
+ if fnamemodify(file, ':p:8') ==? fnamemodify(file, ':p')
+ throw 'Skipped: 8.3 short names are not created on this volume'
+ endif
+ call writefile([], dir . '/bar.vim', 'D')
+
+ let matches = map(split(glob(dir . '/*.vim'), "
"), {_, v -> fnamemodify(v, ':t')})
+ call assert_equal(['bar.vim'], matches)
+
+ " A pattern that is a short name still matches.
+ let short = fnamemodify(file, ':p:8:t')
+ call assert_equal([file], split(glob(dir . '/' . short), "
"))
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index fe82bcdc4..c69281a7a 100644
--- a/src/version.c
+++ b/src/version.c
@@ -758,6 +758,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 893,
/**/
892,
/**/