From: Hirohito Higashi Date: Sat, 1 Aug 2026 13:47:20 +0000 (+0000) Subject: patch 9.2.0893: MS-Windows: "*.vim" also matches files with a longer extension X-Git-Tag: v9.2.0893^0 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8e5d1761ce5d3a5af565d1828f53fa56687bc3c1;p=thirdparty%2Fvim.git 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) Signed-off-by: Hirohito Higashi Signed-off-by: Christian Brabandt --- diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index 4789b8c3b6..3b2f65a9c9 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 e70b9c300b..388ce7af17 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 a1d9d9816e..7bd72ebf75 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'), "\n"), {_, 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), "\n")) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index fe82bcdc4a..c69281a7ad 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, /**/