Skip to content

Commit 3f39697

Browse files
committed
patch 8.1.2234: get_short_pathname() fails depending on encoding
Problem: get_short_pathname() fails depending on encoding. Solution: Use the wide version of the library function. (closes #5129)
1 parent 69bf634 commit 3f39697

3 files changed

Lines changed: 62 additions & 10 deletions

File tree

src/filepath.c

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,56 @@
3030
get_short_pathname(char_u **fnamep, char_u **bufp, int *fnamelen)
3131
{
3232
int l, len;
33-
char_u *newbuf;
33+
WCHAR *newbuf;
34+
WCHAR *wfname;
3435

35-
len = *fnamelen;
36-
l = GetShortPathName((LPSTR)*fnamep, (LPSTR)*fnamep, len);
36+
len = MAXPATHL;
37+
newbuf = malloc(len * sizeof(*newbuf));
38+
if (newbuf == NULL)
39+
return FAIL;
40+
41+
wfname = enc_to_utf16(*fnamep, NULL);
42+
if (wfname == NULL)
43+
{
44+
vim_free(newbuf);
45+
return FAIL;
46+
}
47+
48+
l = GetShortPathNameW(wfname, newbuf, len);
3749
if (l > len - 1)
3850
{
3951
// If that doesn't work (not enough space), then save the string
4052
// and try again with a new buffer big enough.
41-
newbuf = vim_strnsave(*fnamep, l);
53+
WCHAR *newbuf_t = newbuf;
54+
newbuf = vim_realloc(newbuf, (l + 1) * sizeof(*newbuf));
4255
if (newbuf == NULL)
56+
{
57+
vim_free(wfname);
58+
vim_free(newbuf_t);
4359
return FAIL;
44-
45-
vim_free(*bufp);
46-
*fnamep = *bufp = newbuf;
47-
60+
}
4861
// Really should always succeed, as the buffer is big enough.
49-
l = GetShortPathName((LPSTR)*fnamep, (LPSTR)*fnamep, l+1);
62+
l = GetShortPathNameW(wfname, newbuf, l+1);
63+
}
64+
if (l != 0)
65+
{
66+
char_u *p = utf16_to_enc(newbuf, NULL);
67+
if (p != NULL)
68+
{
69+
vim_free(*bufp);
70+
*fnamep = *bufp = p;
71+
}
72+
else
73+
{
74+
vim_free(wfname);
75+
vim_free(newbuf);
76+
return FAIL;
77+
}
5078
}
79+
vim_free(wfname);
80+
vim_free(newbuf);
5181

52-
*fnamelen = l;
82+
*fnamelen = l == 0 ? l : STRLEN(*bufp);
5383
return OK;
5484
}
5585

src/testdir/test_shortpathname.vim

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
" Test for shortpathname ':8' extension.
22
" Only for use on Win32 systems!
33

4+
set encoding=utf-8
5+
scriptencoding utf-8
6+
47
source check.vim
58
CheckMSWindows
69

@@ -67,3 +70,20 @@ func Test_ColonEight()
6770

6871
exe "cd " . save_dir
6972
endfunc
73+
74+
func Test_ColonEight_MultiByte()
75+
let dir = 'Xtest'
76+
77+
let file = dir . '/日本語のファイル.txt'
78+
79+
call mkdir(dir)
80+
call writefile([], file)
81+
82+
let sfile = fnamemodify(file, ':8')
83+
84+
call assert_notequal(file, sfile)
85+
call assert_match('\~', sfile)
86+
87+
call delete(file)
88+
call delete(dir, 'd')
89+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,8 @@ static char *(features[]) =
741741

742742
static int included_patches[] =
743743
{ /* Add new patch number below this line */
744+
/**/
745+
2234,
744746
/**/
745747
2233,
746748
/**/

0 commit comments

Comments
 (0)