diff options
Diffstat (limited to 'src/nvim/path.c')
-rw-r--r-- | src/nvim/path.c | 34 |
1 files changed, 18 insertions, 16 deletions
diff --git a/src/nvim/path.c b/src/nvim/path.c index 6c6a6f58c0..fd2b92e30d 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -613,7 +613,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 @@ -625,9 +624,9 @@ 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. - char *buf = xmalloc(MAXPATHL); + // 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); // Find the first part in the path name that contains a wildcard. // When EW_ICASE is set every letter is considered to be a wildcard. @@ -656,10 +655,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; @@ -713,13 +712,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; @@ -731,6 +731,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) @@ -738,21 +739,22 @@ 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))) { - STRCPY(s, name); - 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 // find matches. - STRCPY(buf + len, "/**"); // NOLINT - STRCPY(buf + len + 3, path_end); + vim_snprintf(buf + len, buflen - len, "/**%s", path_end); // NOLINT stardepth++; do_path_expand(gap, buf, len + 1, flags, true); stardepth--; } - STRCPY(buf + len, path_end); + vim_snprintf(buf + len, buflen - len, "%s", path_end); if (path_has_exp_wildcard(path_end)) { // handle more wildcards // need to expand another component of the path // remove backslashes for the remaining components only |