diff options
| author | zeertzjq <zeertzjq@outlook.com> | 2025-03-15 17:34:56 +0800 |
|---|---|---|
| committer | github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> | 2025-03-15 11:21:12 +0000 |
| commit | 0c995c0efba092f149fc314a43327db7d105e1ad (patch) | |
| tree | 586155db933c577b347a8d2e1eed2b4878804dd1 /src/nvim/path.c | |
| parent | aab7129abe39d3433facb9994998bede3a4299e1 (diff) | |
vim-patch:9.1.1204: MS-Windows: crash when passing long string to expand() (#32902)release-0.10
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#16896
https://github.com/vim/vim/commit/00a749bd90e6b84e7e5132691d73fe9aa3fdff05
(cherry picked from commit ec8fc2874344c7e25f8cbb6894cde526164ea756)
Diffstat (limited to 'src/nvim/path.c')
| -rw-r--r-- | src/nvim/path.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/src/nvim/path.c b/src/nvim/path.c index eeef8a2ffd..7470b081dc 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -619,7 +619,6 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in FUNC_ATTR_NONNULL_ALL { int start_len = gap->ga_len; - size_t len; bool starstar = false; 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 - // length may be quite a bit longer, thus use the maximum possible length. + // Make room for file name (a bit too much to stay on the safe side). const size_t buflen = strlen(path) + MAXPATHL; 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; } - len = (size_t)(utfc_ptr2len(path_end)); - memcpy(p, path_end, len); - p += len; - path_end += len; + int charlen = utfc_ptr2len(path_end); + memcpy(p, path_end, (size_t)charlen); + p += charlen; + path_end += charlen; } e = p; *e = NUL; @@ -720,13 +718,14 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in return 0; } + size_t 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. if (!didstar && stardepth < 100 && starstar && e - s == 2 && *path_end == '/') { - STRCPY(s, path_end + 1); + vim_snprintf(s, buflen - len, "%s", path_end + 1); stardepth++; - do_path_expand(gap, buf, (size_t)(s - buf), flags, true); + do_path_expand(gap, buf, len, flags, true); stardepth--; } *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; scandir_next_with_dots(NULL); // initialize while (!got_int && (name = scandir_next_with_dots(&dir)) != NULL) { + len = (size_t)(s - buf); if ((name[0] != '.' || starts_with_dot || ((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))) && ((regmatch.regprog != NULL && vim_regexec(®match, name, 0)) || ((flags & EW_NOTWILD) - && path_fnamencmp(path + (s - buf), name, (size_t)(e - s)) == 0))) { - xstrlcpy(s, name, buflen - (size_t)(s - buf)); - len = strlen(buf); + && path_fnamencmp(path + len, name, (size_t)(e - s)) == 0))) { + len += (size_t)vim_snprintf(s, buflen - len, "%s", name); + if (len + 1 >= buflen) { + continue; + } if (starstar && stardepth < 100) { // For "**" in the pattern first go deeper in the tree to |
