patch 9.1.1515: Coverity complains about potential unterminated strings
Commit:
https://github.com/vim/vim/commit/21449ee49c28ec7b481d3a0f1dbc1be9286efb5c
Author: glepnir <[email protected]>
Date: Sun Jul 6 11:02:51 2025 +0200
patch 9.1.1515: Coverity complains about potential unterminated strings
Problem: memcpy() in ExpandRTDir_int() may create unterminated strings
Solution: Use vim_snprintf() to construct complete paths safely
(glepnir).
related: neovim/neovim#34795
closes: #17669
Signed-off-by: glepnir <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
diff --git a/src/scriptfile.c b/src/scriptfile.c
index 856d00fbb..9535cef55 100644
--- a/src/scriptfile.c
+++ b/src/scriptfile.c
@@ -1128,43 +1128,51 @@ ExpandRTDir_int(
{
for (int i = 0; dirnames[i] != NULL; ++i)
{
- size_t buf_len = STRLEN(dirnames[i]) + pat_len + 22;
+ const size_t buf_len = STRLEN(dirnames[i]) + pat_len + 64;
char *buf = alloc(buf_len);
if (buf == NULL)
{
ga_clear_strings(gap);
return;
}
- char *tail = buf + 15;
- size_t tail_buflen = buf_len - 15;
int glob_flags = 0;
int expand_dirs = FALSE;
- if (*(dirnames[i]) == NUL) // empty dir used for :runtime
- vim_snprintf(tail, tail_buflen, "%s*.vim", pat);
- else
- vim_snprintf(tail, tail_buflen, "%s/%s*.vim", dirnames[i], pat);
+ // Build base pattern
+ vim_snprintf(buf, buf_len, "%s%s%s%s",
+ *dirnames[i] ? dirnames[i] : "", *dirnames[i] ? "/" : "",
+ pat, "*.vim");
expand:
if ((flags & DIP_NORTP) == 0)
- globpath(p_rtp, (char_u *)tail, gap, glob_flags, expand_dirs);
+ globpath(p_rtp, (char_u *)buf, gap, glob_flags, expand_dirs);
if (flags & DIP_START)
{
- memcpy(tail - 15, "pack/*/start/*/", 15);
- globpath(p_pp, (char_u *)tail - 15, gap, glob_flags, expand_dirs);
+ // Build complete search path: pack/*/start/*/dirnames[i]/pat*.vim
+ vim_snprintf(buf, buf_len, "pack/*/start/*/%s%s%s%s",
+ *dirnames[i] ? dirnames[i] : "",
+ *dirnames[i] ? "/" : "",
+ pat,
+ expand_dirs ? "*" : "*.vim");
+ globpath(p_pp, (char_u *)buf, gap, glob_flags, expand_dirs);
}
if (flags & DIP_OPT)
{
- memcpy(tail - 13, "pack/*/opt/*/", 13);
- globpath(p_pp, (char_u *)tail - 13, gap, glob_flags, expand_dirs);
+ // Build complete search path: pack/*/opt/*/dirnames[i]/pat*.vim
+ vim_snprintf(buf, buf_len, "pack/*/opt/*/%s%s%s%s",
+ *dirnames[i] ? dirnames[i] : "",
+ *dirnames[i] ? "/" : "", pat,
+ expand_dirs ? "*" : "*.vim");
+ globpath(p_pp, (char_u *)buf, gap, glob_flags, expand_dirs);
}
- if (*(dirnames[i]) == NUL && !expand_dirs)
+ // Second round for directories
+ if (*dirnames[i] == NUL && !expand_dirs)
{
// expand dir names in another round
- vim_snprintf(tail, tail_buflen, "%s*", pat);
+ vim_snprintf(buf, buf_len, "%s*", pat);
glob_flags = WILD_ADD_SLASH;
expand_dirs = TRUE;
goto expand;
@@ -1175,8 +1183,10 @@ expand:
int pat_pathsep_cnt = 0;
for (size_t i = 0; i < pat_len; ++i)
+ {
if (vim_ispathsep(pat[i]))
++pat_pathsep_cnt;
+ }
for (int i = 0; i < gap->ga_len; ++i)
{
@@ -1191,9 +1201,11 @@ expand:
int match_pathsep_cnt = (e > s && e[-1] == '/') ? -1 : 0;
for (s = e; s > match; MB_PTR_BACK(match, s))
+ {
if (s < match || (vim_ispathsep(*s)
&& ++match_pathsep_cnt > pat_pathsep_cnt))
break;
+ }
++s;
if (s != match)
mch_memmove(match, s, e - s + 1);
diff --git a/src/version.c b/src/version.c
index 1cf223d18..f9e0bea34 100644
--- a/src/version.c
+++ b/src/version.c
@@ -719,6 +719,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 1515,
/**/
1514,
/**/
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/vim_dev/E1uYLSh-006PhK-9p%40256bit.org.