mirror of
https://github.com/neovim/neovim
synced 2025-07-15 16:51:49 +00:00
vim-patch:9.1.1204: MS-Windows: crash when passing long string to expand() (#32902)
Problem: MS-Windows: crash when passing long string to expand() with 'wildignorecase'. Solution: Use the same buflen as unix_expandpath() in dos_expandpath(). Remove an unnecessary STRLEN() while at it (zeertzjq). closes: vim/vim#1689600a749bd90
(cherry picked from commitec8fc28743
)
This commit is contained in:
committed by
github-actions[bot]
parent
aab7129abe
commit
0c995c0efb
@ -619,7 +619,6 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
|
|||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
int start_len = gap->ga_len;
|
int start_len = gap->ga_len;
|
||||||
size_t len;
|
|
||||||
bool starstar = false;
|
bool starstar = false;
|
||||||
static int stardepth = 0; // depth for "**" expansion
|
static int stardepth = 0; // depth for "**" expansion
|
||||||
|
|
||||||
@ -631,8 +630,7 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make room for file name. When doing encoding conversion the actual
|
// Make room for file name (a bit too much to stay on the safe side).
|
||||||
// length may be quite a bit longer, thus use the maximum possible length.
|
|
||||||
const size_t buflen = strlen(path) + MAXPATHL;
|
const size_t buflen = strlen(path) + MAXPATHL;
|
||||||
char *buf = xmalloc(buflen);
|
char *buf = xmalloc(buflen);
|
||||||
|
|
||||||
@ -663,10 +661,10 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
|
|||||||
) {
|
) {
|
||||||
e = p;
|
e = p;
|
||||||
}
|
}
|
||||||
len = (size_t)(utfc_ptr2len(path_end));
|
int charlen = utfc_ptr2len(path_end);
|
||||||
memcpy(p, path_end, len);
|
memcpy(p, path_end, (size_t)charlen);
|
||||||
p += len;
|
p += charlen;
|
||||||
path_end += len;
|
path_end += charlen;
|
||||||
}
|
}
|
||||||
e = p;
|
e = p;
|
||||||
*e = NUL;
|
*e = NUL;
|
||||||
@ -720,13 +718,14 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t len = (size_t)(s - buf);
|
||||||
// If "**" is by itself, this is the first time we encounter it and more
|
// If "**" is by itself, this is the first time we encounter it and more
|
||||||
// is following then find matches without any directory.
|
// is following then find matches without any directory.
|
||||||
if (!didstar && stardepth < 100 && starstar && e - s == 2
|
if (!didstar && stardepth < 100 && starstar && e - s == 2
|
||||||
&& *path_end == '/') {
|
&& *path_end == '/') {
|
||||||
STRCPY(s, path_end + 1);
|
vim_snprintf(s, buflen - len, "%s", path_end + 1);
|
||||||
stardepth++;
|
stardepth++;
|
||||||
do_path_expand(gap, buf, (size_t)(s - buf), flags, true);
|
do_path_expand(gap, buf, len, flags, true);
|
||||||
stardepth--;
|
stardepth--;
|
||||||
}
|
}
|
||||||
*s = NUL;
|
*s = NUL;
|
||||||
@ -738,6 +737,7 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
|
|||||||
const char *name;
|
const char *name;
|
||||||
scandir_next_with_dots(NULL); // initialize
|
scandir_next_with_dots(NULL); // initialize
|
||||||
while (!got_int && (name = scandir_next_with_dots(&dir)) != NULL) {
|
while (!got_int && (name = scandir_next_with_dots(&dir)) != NULL) {
|
||||||
|
len = (size_t)(s - buf);
|
||||||
if ((name[0] != '.'
|
if ((name[0] != '.'
|
||||||
|| starts_with_dot
|
|| starts_with_dot
|
||||||
|| ((flags & EW_DODOT)
|
|| ((flags & EW_DODOT)
|
||||||
@ -745,9 +745,11 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
|
|||||||
&& (name[1] != '.' || name[2] != NUL)))
|
&& (name[1] != '.' || name[2] != NUL)))
|
||||||
&& ((regmatch.regprog != NULL && vim_regexec(®match, name, 0))
|
&& ((regmatch.regprog != NULL && vim_regexec(®match, name, 0))
|
||||||
|| ((flags & EW_NOTWILD)
|
|| ((flags & EW_NOTWILD)
|
||||||
&& path_fnamencmp(path + (s - buf), name, (size_t)(e - s)) == 0))) {
|
&& path_fnamencmp(path + len, name, (size_t)(e - s)) == 0))) {
|
||||||
xstrlcpy(s, name, buflen - (size_t)(s - buf));
|
len += (size_t)vim_snprintf(s, buflen - len, "%s", name);
|
||||||
len = strlen(buf);
|
if (len + 1 >= buflen) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (starstar && stardepth < 100) {
|
if (starstar && stardepth < 100) {
|
||||||
// For "**" in the pattern first go deeper in the tree to
|
// For "**" in the pattern first go deeper in the tree to
|
||||||
|
@ -143,4 +143,11 @@ func Test_expand_wildignore()
|
|||||||
set wildignore&
|
set wildignore&
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Passing a long string to expand with 'wildignorecase' should not crash Vim.
|
||||||
|
func Test_expand_long_str()
|
||||||
|
set wildignorecase
|
||||||
|
call expand('a'->repeat(99999))
|
||||||
|
set wildignorecase&
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
Reference in New Issue
Block a user