mirror of
https://github.com/neovim/neovim.git
synced 2025-09-05 19:08:15 +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.
|
// TODO(bfredl): this is bullshit, expandpath should not reinvent path logic.
|
||||||
for (int i = 0; dirnames[i] != NULL; i++) {
|
for (int i = 0; dirnames[i] != NULL; i++) {
|
||||||
const size_t buf_len = strlen(dirnames[i]) + pat_len + 31;
|
const size_t buf_len = strlen(dirnames[i]) + pat_len + 64;
|
||||||
char *const buf = xmalloc(buf_len);
|
char *buf = xmalloc(buf_len);
|
||||||
char *const tail = buf + 15;
|
|
||||||
const size_t tail_buflen = buf_len - 15;
|
|
||||||
int glob_flags = 0;
|
int glob_flags = 0;
|
||||||
bool expand_dirs = false;
|
bool expand_dirs = false;
|
||||||
|
// Build base pattern
|
||||||
if (*dirnames[i] == NUL) { // empty dir used for :runtime
|
snprintf(buf, buf_len, "%s%s%s%s", *dirnames[i] ? dirnames[i] : "", *dirnames[i] ? "/" : "",
|
||||||
snprintf(tail, tail_buflen, "%s*.{vim,lua}", pat);
|
pat, "*.{vim,lua}");
|
||||||
} else {
|
|
||||||
snprintf(tail, tail_buflen, "%s/%s*.{vim,lua}", dirnames[i], pat);
|
|
||||||
}
|
|
||||||
|
|
||||||
expand:
|
expand:
|
||||||
if ((flags & DIP_NORTP) == 0) {
|
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) {
|
if (flags & DIP_START) {
|
||||||
memcpy(tail - 15, "pack/*/start/*/", 15); // NOLINT
|
// pack/*/start/*/ patterns
|
||||||
globpath(p_pp, tail - 15, gap, glob_flags, expand_dirs);
|
snprintf(buf, buf_len, "pack/*/start/*/%s%s%s%s", *dirnames[i] ? dirnames[i] : "", // NOLINT
|
||||||
memcpy(tail - 8, "start/*/", 8); // NOLINT
|
*dirnames[i] ? "/" : "", pat, expand_dirs ? "*" : "*.{vim,lua}");
|
||||||
globpath(p_pp, tail - 8, gap, glob_flags, expand_dirs);
|
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) {
|
if (flags & DIP_OPT) {
|
||||||
memcpy(tail - 13, "pack/*/opt/*/", 13); // NOLINT
|
// pack/*/opt/*/ patterns
|
||||||
globpath(p_pp, tail - 13, gap, glob_flags, expand_dirs);
|
snprintf(buf, buf_len, "pack/*/opt/*/%s%s%s%s", *dirnames[i] ? dirnames[i] : "", // NOLINT
|
||||||
memcpy(tail - 6, "opt/*/", 6); // NOLINT
|
*dirnames[i] ? "/" : "", pat, expand_dirs ? "*" : "*.{vim,lua}");
|
||||||
globpath(p_pp, tail - 6, gap, glob_flags, expand_dirs);
|
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) {
|
if (*dirnames[i] == NUL && !expand_dirs) {
|
||||||
// expand dir names in another round
|
snprintf(buf, buf_len, "%s*", pat);
|
||||||
snprintf(tail, tail_buflen, "%s*", pat);
|
|
||||||
glob_flags = WILD_ADD_SLASH;
|
glob_flags = WILD_ADD_SLASH;
|
||||||
expand_dirs = true;
|
expand_dirs = true;
|
||||||
goto expand;
|
goto expand;
|
||||||
|
Reference in New Issue
Block a user