mirror of
https://github.com/neovim/neovim.git
synced 2026-07-14 13:20:35 +00:00
fix(coverity): RESOURCE_LEAK, USE_AFTER_FREE
/src/nvim/ex_docmd.c: 5033 in ex_restart()
5027 // The address after --listen may be in use by the current server.
5028 if (i > 0 && strequal(arg, "--listen")) {
5029 const listitem_T *next_li = li->li_next;
5030 if (next_li != NULL) {
5031 const char *addr = tv_get_string(TV_LIST_ITEM_TV(next_li));
5032 if (strstr(addr, ":") || strstr(addr, "/") || strstr(addr, "\\")) {
>>> CID 649201: Resource leaks (RESOURCE_LEAK)
>>> Overwriting "listen_arg" in "listen_arg = xstrdup(addr)" leaks the storage that "listen_arg" points to.
5033 listen_arg = TO_SLASH_SAVE(addr);
5034 #ifdef MSWIN
5035 // On Windows, don't pass --listen to new server (named pipe can't be reused immediately).
5036 // Instead pass the address via RPC; new server rebinds after startup.
5037 li = next_li;
5038 continue;
*** CID 649200: Memory - illegal accesses (USE_AFTER_FREE)
/src/nvim/eval/fs.c: 228 in modify_fname()
222
223 // ":h" - head, remove "/file_name", can be repeated
224 // Don't remove the logical root, see `FileInfo`.
225 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') {
226 valid |= VALID_HEAD;
227 *usedlen += 2;
>>> CID 649200: Memory - illegal accesses (USE_AFTER_FREE)
>>> Using freed pointer "s".
228 while (tail > s && after_pathsep(s, tail)) {
229 MB_PTR_BACK(*fnamep, tail);
230 }
231 *fnamelen = tail <= s ? (size_t)(s - *fnamep) : (size_t)(tail - *fnamep);
232 if (*fnamelen == 0) {
233 // Result is empty. Turn it into "." to make ":cd %:h" work.
This commit is contained in:
@@ -233,6 +233,7 @@ repeat:
|
||||
// Result is empty. Turn it into "." to make ":cd %:h" work.
|
||||
xfree(*bufp);
|
||||
*bufp = *fnamep = tail = xstrdup(".");
|
||||
s = *fnamep; // s pointed into the freed buffer.
|
||||
*fnamelen = 1;
|
||||
} else {
|
||||
while (tail > s && !after_pathsep(s, tail)) {
|
||||
|
||||
@@ -5030,6 +5030,7 @@ static void ex_restart(exarg_T *eap)
|
||||
if (next_li != NULL) {
|
||||
const char *addr = tv_get_string(TV_LIST_ITEM_TV(next_li));
|
||||
if (strstr(addr, ":") || strstr(addr, "/") || strstr(addr, "\\")) {
|
||||
XFREE_CLEAR(listen_arg);
|
||||
listen_arg = TO_SLASH_SAVE(addr);
|
||||
#ifdef MSWIN
|
||||
// On Windows, don't pass --listen to new server (named pipe can't be reused immediately).
|
||||
|
||||
@@ -104,6 +104,10 @@ describe('fnamemodify()', function()
|
||||
it('handles :h', function()
|
||||
-- generic path
|
||||
eq('.', fnamemodify('hello.txt', ':h'))
|
||||
-- Repeated ":h" on a bare name: the first ":h" replaces the buffer with ".", the
|
||||
-- next must re-anchor into it and not read the freed buffer (Coverity CID 649200).
|
||||
eq('.', fnamemodify('hello.txt', ':h:h'))
|
||||
eq('.', fnamemodify('hello.txt', ':h:h:h'))
|
||||
eq('path/to', fnamemodify('path/to/hello.txt', ':h'))
|
||||
eq('/', fnamemodify('/', ':h'))
|
||||
eq('/', fnamemodify('/foo', ':h'))
|
||||
|
||||
Reference in New Issue
Block a user