mirror of
https://github.com/neovim/neovim.git
synced 2025-11-22 10:06:33 +00:00
fix(terminal): coverity USE_AFTER_FREE #18978
Problem:
Coverity reports use after free:
*** CID 352784: Memory - illegal accesses (USE_AFTER_FREE)
/src/nvim/buffer.c: 1508 in set_curbuf()
1502 if (old_tw != curbuf->b_p_tw) {
1503 check_colorcolumn(curwin);
1504 }
1505 }
1506
1507 if (bufref_valid(&prevbufref) && prevbuf->terminal != NULL) {
>>> CID 352784: Memory - illegal accesses (USE_AFTER_FREE)
>>> Calling "terminal_check_size" dereferences freed pointer "prevbuf->terminal".
1508 terminal_check_size(prevbuf->terminal);
1509 }
1510 }
1511
1512 /// Enter a new current buffer.
1513 /// Old curbuf must have been abandoned already! This also means "curbuf" may
Solution:
Change terminal_destroy and terminal_close to set caller storage to NULL,
similar to XFREE_CLEAR. This aligns with the pattern found already in:
terminal_destroy e897ccad3e
term_delayed_free 3e59c1e20d
This commit is contained in:
@@ -275,8 +275,12 @@ Terminal *terminal_open(buf_T *buf, TerminalOptions opts)
|
||||
return rv;
|
||||
}
|
||||
|
||||
void terminal_close(Terminal *term, int status)
|
||||
/// Closes the Terminal buffer.
|
||||
///
|
||||
/// May call terminal_destroy, which sets caller storage to NULL.
|
||||
void terminal_close(Terminal **termpp, int status)
|
||||
{
|
||||
Terminal *term = *termpp;
|
||||
if (term->destroy) {
|
||||
return;
|
||||
}
|
||||
@@ -285,7 +289,7 @@ void terminal_close(Terminal *term, int status)
|
||||
if (entered_free_all_mem) {
|
||||
// If called from close_buffer() inside free_all_mem(), the main loop has
|
||||
// already been freed, so it is not safe to call the close callback here.
|
||||
terminal_destroy(term);
|
||||
terminal_destroy(termpp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -586,8 +590,11 @@ static int terminal_execute(VimState *state, int key)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void terminal_destroy(Terminal *term)
|
||||
/// Frees the given Terminal structure and sets the caller storage to NULL (in the spirit of
|
||||
/// XFREE_CLEAR).
|
||||
void terminal_destroy(Terminal **termpp)
|
||||
{
|
||||
Terminal *term = *termpp;
|
||||
buf_T *buf = handle_get_buffer(term->buf_handle);
|
||||
if (buf) {
|
||||
term->buf_handle = 0;
|
||||
@@ -608,6 +615,7 @@ void terminal_destroy(Terminal *term)
|
||||
xfree(term->sb_buffer);
|
||||
vterm_free(term->vt);
|
||||
xfree(term);
|
||||
*termpp = NULL; // coverity[dead-store]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user