mirror of
https://github.com/neovim/neovim.git
synced 2025-09-16 08:18:17 +00:00
provider/RPC: apply_autocmds_group(): fix double-free
During provider dispatch, eval_call_provider() saves global
state--including pointers, such as `autocmd_fname`--into
`provider_caller_scope` which is later restored by f_rpcrequest().
But `autocmd_fname` is special-cased in eval_vars(), for performance
(see Vim patch 7.2.021; this is also the singular purpose of the
`autocmd_fname_full` global. Yay!)
If eval_vars() frees `autocmd_fname` then its provider-RPC-scoped alias
becomes a problem.
Solution: Don't free autocmd_fname in eval_vars(), just copy into it.
closes #5245
closes #5617
Reference
------------------------------------------------------------------------
Vim patch 7.2.021
f6dad43c98
Problem: When executing autocommands getting the full file name may be
slow. (David Kotchan)
Solution: Postpone calling FullName_save() until autocmd_fname is used.
vim_dev discussion (2008): "Problem with CursorMoved AutoCommand when
Editing Files on a Remote WIndows Share"
https://groups.google.com/d/msg/vim_dev/kj95weZa_eE/GTgj4aq5sIgJ
This commit is contained in:
@@ -8547,15 +8547,16 @@ eval_vars (
|
||||
break;
|
||||
|
||||
case SPEC_AFILE: /* file name for autocommand */
|
||||
result = autocmd_fname;
|
||||
if (result != NULL && !autocmd_fname_full) {
|
||||
/* Still need to turn the fname into a full path. It is
|
||||
* postponed to avoid a delay when <afile> is not used. */
|
||||
autocmd_fname_full = TRUE;
|
||||
result = (char_u *)FullName_save((char *)autocmd_fname, FALSE);
|
||||
xfree(autocmd_fname);
|
||||
autocmd_fname = result;
|
||||
if (autocmd_fname != NULL && !autocmd_fname_full) {
|
||||
// Still need to turn the fname into a full path. It was
|
||||
// postponed to avoid a delay when <afile> is not used.
|
||||
autocmd_fname_full = true;
|
||||
result = (char_u *)FullName_save((char *)autocmd_fname, false);
|
||||
// Copy into `autocmd_fname`, don't reassign it. #8165
|
||||
xstrlcpy((char *)autocmd_fname, (char *)result, MAXPATHL);
|
||||
xfree(result);
|
||||
}
|
||||
result = autocmd_fname;
|
||||
if (result == NULL) {
|
||||
*errormsg = (char_u *)_(
|
||||
"E495: no autocommand file name to substitute for \"<afile>\"");
|
||||
|
Reference in New Issue
Block a user