mirror of
https://github.com/neovim/neovim
synced 2025-07-15 16:51:49 +00:00
Problem: Coverity reports string null termination issue: *** CID 569464: Memory - string handling (STRING_NULL) /src/nvim/runtime.c: 1374 in ExpandRTDir_int() 1372 if (flags & DIP_START) { 1373 memcpy(tail - 15, "pack/*/start/*/", 15); // NOLINT >>> CID 569464: Memory - string handling (STRING_NULL) >>> Passing unterminated string "tail - 15" to "globpath", which expects a null-terminated string. 1374 globpath(p_pp, tail - 15, gap, glob_flags, expand_dirs); Similar issues occur at lines 1376, 1381, and 1383 where memcpy() constructs strings passed to globpath() without null termination. Solution: Replace dangerous pointer arithmetic and memcpy() with direct snprintf() construction of complete search paths. This eliminates the need for buffer reuse through pointer offsets and ensures all strings passed to globpath() are properly null-terminated. vim-patch:9.1.1515: Coverity complains about potential unterminated strings
This commit is contained in:
@ -1351,41 +1351,46 @@ static void ExpandRTDir_int(char *pat, size_t pat_len, int flags, bool keep_ext,
|
||||
{
|
||||
// TODO(bfredl): this is bullshit, expandpath should not reinvent path logic.
|
||||
for (int i = 0; dirnames[i] != NULL; i++) {
|
||||
const size_t buf_len = strlen(dirnames[i]) + pat_len + 31;
|
||||
char *const buf = xmalloc(buf_len);
|
||||
char *const tail = buf + 15;
|
||||
const size_t tail_buflen = buf_len - 15;
|
||||
const size_t buf_len = strlen(dirnames[i]) + pat_len + 64;
|
||||
char *buf = xmalloc(buf_len);
|
||||
int glob_flags = 0;
|
||||
bool expand_dirs = false;
|
||||
|
||||
if (*dirnames[i] == NUL) { // empty dir used for :runtime
|
||||
snprintf(tail, tail_buflen, "%s*.{vim,lua}", pat);
|
||||
} else {
|
||||
snprintf(tail, tail_buflen, "%s/%s*.{vim,lua}", dirnames[i], pat);
|
||||
}
|
||||
// Build base pattern
|
||||
snprintf(buf, buf_len, "%s%s%s%s", *dirnames[i] ? dirnames[i] : "", *dirnames[i] ? "/" : "",
|
||||
pat, "*.{vim,lua}");
|
||||
|
||||
expand:
|
||||
if ((flags & DIP_NORTP) == 0) {
|
||||
globpath(p_rtp, tail, gap, glob_flags, expand_dirs);
|
||||
globpath(p_rtp, buf, gap, glob_flags, expand_dirs);
|
||||
}
|
||||
|
||||
if (flags & DIP_START) {
|
||||
memcpy(tail - 15, "pack/*/start/*/", 15); // NOLINT
|
||||
globpath(p_pp, tail - 15, gap, glob_flags, expand_dirs);
|
||||
memcpy(tail - 8, "start/*/", 8); // NOLINT
|
||||
globpath(p_pp, tail - 8, gap, glob_flags, expand_dirs);
|
||||
// pack/*/start/*/ patterns
|
||||
snprintf(buf, buf_len, "pack/*/start/*/%s%s%s%s", *dirnames[i] ? dirnames[i] : "", // NOLINT
|
||||
*dirnames[i] ? "/" : "", pat, expand_dirs ? "*" : "*.{vim,lua}");
|
||||
globpath(p_pp, buf, gap, glob_flags, expand_dirs);
|
||||
|
||||
// start/*/ patterns
|
||||
snprintf(buf, buf_len, "start/*/%s%s%s%s", *dirnames[i] ? dirnames[i] : "", // NOLINT
|
||||
*dirnames[i] ? "/" : "", pat, expand_dirs ? "*" : "*.{vim,lua}");
|
||||
globpath(p_pp, buf, gap, glob_flags, expand_dirs);
|
||||
}
|
||||
|
||||
if (flags & DIP_OPT) {
|
||||
memcpy(tail - 13, "pack/*/opt/*/", 13); // NOLINT
|
||||
globpath(p_pp, tail - 13, gap, glob_flags, expand_dirs);
|
||||
memcpy(tail - 6, "opt/*/", 6); // NOLINT
|
||||
globpath(p_pp, tail - 6, gap, glob_flags, expand_dirs);
|
||||
// pack/*/opt/*/ patterns
|
||||
snprintf(buf, buf_len, "pack/*/opt/*/%s%s%s%s", *dirnames[i] ? dirnames[i] : "", // NOLINT
|
||||
*dirnames[i] ? "/" : "", pat, expand_dirs ? "*" : "*.{vim,lua}");
|
||||
globpath(p_pp, buf, gap, glob_flags, expand_dirs);
|
||||
|
||||
// opt/*/ patterns
|
||||
snprintf(buf, buf_len, "opt/*/%s%s%s%s", *dirnames[i] ? dirnames[i] : "", // NOLINT
|
||||
*dirnames[i] ? "/" : "", pat, expand_dirs ? "*" : "*.{vim,lua}");
|
||||
globpath(p_pp, buf, gap, glob_flags, expand_dirs);
|
||||
}
|
||||
|
||||
// Second round for directories
|
||||
if (*dirnames[i] == NUL && !expand_dirs) {
|
||||
// expand dir names in another round
|
||||
snprintf(tail, tail_buflen, "%s*", pat);
|
||||
snprintf(buf, buf_len, "%s*", pat);
|
||||
glob_flags = WILD_ADD_SLASH;
|
||||
expand_dirs = true;
|
||||
goto expand;
|
||||
|
Reference in New Issue
Block a user