mirror of
https://github.com/neovim/neovim.git
synced 2026-07-09 19:09:39 +00:00
vim-patch:9.2.0708: Leaks in do_autocmd in error case (#40386)
Problem: Leak in do_autocmd in error case (Cheng)
Solution: goto err_exit in the error case and clean up, make the double
++once an actual error
closes: vim/vim#20606
98f5171ef6
Co-authored-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
@@ -763,7 +763,7 @@ void do_autocmd(exarg_T *eap, char *arg_in, int forceit)
|
||||
char *arg = arg_in;
|
||||
char *envpat = NULL;
|
||||
char *cmd;
|
||||
bool need_free = false;
|
||||
bool cmd_need_free = false;
|
||||
bool nested = false;
|
||||
bool once = false;
|
||||
int group;
|
||||
@@ -832,7 +832,7 @@ void do_autocmd(exarg_T *eap, char *arg_in, int forceit)
|
||||
}
|
||||
|
||||
if (invalid_flags) {
|
||||
return;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
// Find the start of the commands.
|
||||
@@ -840,9 +840,9 @@ void do_autocmd(exarg_T *eap, char *arg_in, int forceit)
|
||||
if (*cmd != NUL) {
|
||||
cmd = expand_sfile(cmd);
|
||||
if (cmd == NULL) { // some error
|
||||
return;
|
||||
goto err_exit;
|
||||
}
|
||||
need_free = true;
|
||||
cmd_need_free = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -879,7 +879,8 @@ void do_autocmd(exarg_T *eap, char *arg_in, int forceit)
|
||||
}
|
||||
}
|
||||
|
||||
if (need_free) {
|
||||
err_exit:
|
||||
if (cmd_need_free) {
|
||||
xfree(cmd);
|
||||
}
|
||||
xfree(envpat);
|
||||
|
||||
@@ -3126,8 +3126,41 @@ func Test_autocmd_once()
|
||||
close
|
||||
|
||||
call assert_fails('au WinNew * ++once ++once echo bad', 'E983:')
|
||||
call assert_false(exists('#WinNew'))
|
||||
endfunc
|
||||
|
||||
func Test_autocmd_dup_arg()
|
||||
" Duplicate ++once / ++nested, or the legacy "nested" used twice, must
|
||||
" error out *and* not create the autocommand. Using an environment
|
||||
" variable in the pattern also exercises the error-exit path that frees
|
||||
" the expanded pattern (checked by the address/leak sanitizers).
|
||||
augroup XdupTest
|
||||
au!
|
||||
augroup END
|
||||
let $XAUTODIR = 'Xfoo'
|
||||
|
||||
" New behavior: duplicate ++once now aborts, the autocmd is not added
|
||||
call assert_fails('au XdupTest WinNew $XAUTODIR/* ++once ++once echo bad', 'E983:')
|
||||
call assert_false(exists('#XdupTest#WinNew'))
|
||||
|
||||
call assert_fails('au XdupTest WinNew $XAUTODIR/* ++nested ++nested echo bad', 'E983:')
|
||||
call assert_false(exists('#XdupTest#WinNew'))
|
||||
|
||||
call assert_fails('au XdupTest WinNew $XAUTODIR/* nested nested echo bad', 'E983:')
|
||||
call assert_false(exists('#XdupTest#WinNew'))
|
||||
|
||||
" "nested" without "++" is rejected in Vim9 script (also frees the pattern)
|
||||
"call assert_fails('vim9cmd au XdupTest WinNew $XAUTODIR/* nested echo bad', 'E1078:')
|
||||
call assert_false(exists('#XdupTest#WinNew'))
|
||||
|
||||
augroup XdupTest
|
||||
au!
|
||||
augroup END
|
||||
augroup! XdupTest
|
||||
let $XAUTODIR = ''
|
||||
endfunc
|
||||
|
||||
|
||||
func Test_autocmd_bufreadpre()
|
||||
new
|
||||
let b:bufreadpre = 1
|
||||
|
||||
Reference in New Issue
Block a user