mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge #8165 'provider/RPC: fix double-free'
This commit is contained in:
@@ -13814,7 +13814,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
scid_T save_current_SID;
|
||||
uint8_t *save_sourcing_name, *save_autocmd_fname, *save_autocmd_match;
|
||||
linenr_T save_sourcing_lnum;
|
||||
int save_autocmd_fname_full, save_autocmd_bufnr;
|
||||
int save_autocmd_bufnr;
|
||||
void *save_funccalp;
|
||||
|
||||
if (l_provider_call_nesting) {
|
||||
@@ -13825,16 +13825,14 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
save_sourcing_lnum = sourcing_lnum;
|
||||
save_autocmd_fname = autocmd_fname;
|
||||
save_autocmd_match = autocmd_match;
|
||||
save_autocmd_fname_full = autocmd_fname_full;
|
||||
save_autocmd_bufnr = autocmd_bufnr;
|
||||
save_funccalp = save_funccal();
|
||||
//
|
||||
|
||||
current_SID = provider_caller_scope.SID;
|
||||
sourcing_name = provider_caller_scope.sourcing_name;
|
||||
sourcing_lnum = provider_caller_scope.sourcing_lnum;
|
||||
autocmd_fname = provider_caller_scope.autocmd_fname;
|
||||
autocmd_match = provider_caller_scope.autocmd_match;
|
||||
autocmd_fname_full = provider_caller_scope.autocmd_fname_full;
|
||||
autocmd_bufnr = provider_caller_scope.autocmd_bufnr;
|
||||
restore_funccal(provider_caller_scope.funccalp);
|
||||
}
|
||||
@@ -13850,7 +13848,6 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
sourcing_lnum = save_sourcing_lnum;
|
||||
autocmd_fname = save_autocmd_fname;
|
||||
autocmd_match = save_autocmd_match;
|
||||
autocmd_fname_full = save_autocmd_fname_full;
|
||||
autocmd_bufnr = save_autocmd_bufnr;
|
||||
restore_funccal(save_funccalp);
|
||||
}
|
||||
@@ -22448,7 +22445,6 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments)
|
||||
.sourcing_lnum = sourcing_lnum,
|
||||
.autocmd_fname = autocmd_fname,
|
||||
.autocmd_match = autocmd_match,
|
||||
.autocmd_fname_full = autocmd_fname_full,
|
||||
.autocmd_bufnr = autocmd_bufnr,
|
||||
.funccalp = save_funccal()
|
||||
};
|
||||
@@ -22481,7 +22477,8 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments)
|
||||
restore_funccal(provider_caller_scope.funccalp);
|
||||
provider_caller_scope = saved_provider_caller_scope;
|
||||
provider_call_nesting--;
|
||||
|
||||
assert(provider_call_nesting >= 0);
|
||||
|
||||
return rettv;
|
||||
}
|
||||
|
||||
|
||||
@@ -8546,16 +8546,16 @@ eval_vars (
|
||||
resultbuf = result; /* remember allocated string */
|
||||
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;
|
||||
case SPEC_AFILE: // file name for autocommand
|
||||
if (autocmd_fname != NULL && !path_is_absolute_path(autocmd_fname)) {
|
||||
// Still need to turn the fname into a full path. It was
|
||||
// postponed to avoid a delay when <afile> is not used.
|
||||
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>\"");
|
||||
|
||||
@@ -6655,7 +6655,6 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
|
||||
char_u *save_sourcing_name;
|
||||
linenr_T save_sourcing_lnum;
|
||||
char_u *save_autocmd_fname;
|
||||
int save_autocmd_fname_full;
|
||||
int save_autocmd_bufnr;
|
||||
char_u *save_autocmd_match;
|
||||
int save_autocmd_busy;
|
||||
@@ -6728,7 +6727,6 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
|
||||
* Save the autocmd_* variables and info about the current buffer.
|
||||
*/
|
||||
save_autocmd_fname = autocmd_fname;
|
||||
save_autocmd_fname_full = autocmd_fname_full;
|
||||
save_autocmd_bufnr = autocmd_bufnr;
|
||||
save_autocmd_match = autocmd_match;
|
||||
save_autocmd_busy = autocmd_busy;
|
||||
@@ -6755,9 +6753,9 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
|
||||
autocmd_fname = fname_io;
|
||||
}
|
||||
if (autocmd_fname != NULL) {
|
||||
autocmd_fname = vim_strsave(autocmd_fname);
|
||||
// Allocate MAXPATHL for when eval_vars() resolves the fullpath.
|
||||
autocmd_fname = vim_strnsave(autocmd_fname, MAXPATHL);
|
||||
}
|
||||
autocmd_fname_full = false; // call FullName_save() later
|
||||
|
||||
/*
|
||||
* Set the buffer number to be used for <abuf>.
|
||||
@@ -6924,7 +6922,6 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
|
||||
sourcing_lnum = save_sourcing_lnum;
|
||||
xfree(autocmd_fname);
|
||||
autocmd_fname = save_autocmd_fname;
|
||||
autocmd_fname_full = save_autocmd_fname_full;
|
||||
autocmd_bufnr = save_autocmd_bufnr;
|
||||
autocmd_match = save_autocmd_match;
|
||||
current_SID = save_current_SID;
|
||||
|
||||
@@ -416,7 +416,7 @@ EXTERN struct caller_scope {
|
||||
scid_T SID;
|
||||
uint8_t *sourcing_name, *autocmd_fname, *autocmd_match;
|
||||
linenr_T sourcing_lnum;
|
||||
int autocmd_fname_full, autocmd_bufnr;
|
||||
int autocmd_bufnr;
|
||||
void *funccalp;
|
||||
} provider_caller_scope;
|
||||
EXTERN int provider_call_nesting INIT(= 0);
|
||||
@@ -872,7 +872,6 @@ EXTERN char_u *last_cmdline INIT(= NULL); // last command line (for ":)
|
||||
EXTERN char_u *repeat_cmdline INIT(= NULL); // command line for "."
|
||||
EXTERN char_u *new_last_cmdline INIT(= NULL); // new value for last_cmdline
|
||||
EXTERN char_u *autocmd_fname INIT(= NULL); // fname for <afile> on cmdline
|
||||
EXTERN int autocmd_fname_full; // autocmd_fname is full path
|
||||
EXTERN int autocmd_bufnr INIT(= 0); // fnum for <abuf> on cmdline
|
||||
EXTERN char_u *autocmd_match INIT(= NULL); // name for <amatch> on cmdline
|
||||
EXTERN int did_cursorhold INIT(= false); // set when CursorHold t'gerd
|
||||
|
||||
@@ -3,6 +3,7 @@ local eval, command, feed = helpers.eval, helpers.command, helpers.feed
|
||||
local eq, clear, insert = helpers.eq, helpers.clear, helpers.insert
|
||||
local expect, write_file = helpers.expect, helpers.write_file
|
||||
local feed_command = helpers.feed_command
|
||||
local source = helpers.source
|
||||
local missing_provider = helpers.missing_provider
|
||||
|
||||
do
|
||||
@@ -13,7 +14,7 @@ do
|
||||
end
|
||||
end
|
||||
|
||||
describe('python3 commands and functions', function()
|
||||
describe('python3 provider', function()
|
||||
before_each(function()
|
||||
clear()
|
||||
command('python3 import vim')
|
||||
@@ -82,4 +83,20 @@ describe('python3 commands and functions', function()
|
||||
it('py3eval', function()
|
||||
eq({1, 2, {['key'] = 'val'}}, eval([[py3eval('[1, 2, {"key": "val"}]')]]))
|
||||
end)
|
||||
|
||||
it('RPC call to expand("<afile>") during BufDelete #5245 #5617', function()
|
||||
source([=[
|
||||
python3 << EOF
|
||||
import vim
|
||||
def foo():
|
||||
vim.eval('expand("<afile>:p")')
|
||||
vim.eval('bufnr(expand("<afile>:p"))')
|
||||
EOF
|
||||
autocmd BufDelete * python3 foo()
|
||||
autocmd BufUnload * python3 foo()]=])
|
||||
feed_command("exe 'split' tempname()")
|
||||
feed_command("bwipeout!")
|
||||
feed_command('help help')
|
||||
eq(2, eval('1+1')) -- Still alive?
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
|
||||
local eq = helpers.eq
|
||||
local feed = helpers.feed
|
||||
local clear = helpers.clear
|
||||
local funcs = helpers.funcs
|
||||
local meths = helpers.meths
|
||||
local insert = helpers.insert
|
||||
local expect = helpers.expect
|
||||
local command = helpers.command
|
||||
local write_file = helpers.write_file
|
||||
local curbufmeths = helpers.curbufmeths
|
||||
local eq = helpers.eq
|
||||
local eval = helpers.eval
|
||||
local expect = helpers.expect
|
||||
local feed = helpers.feed
|
||||
local feed_command = helpers.feed_command
|
||||
local funcs = helpers.funcs
|
||||
local insert = helpers.insert
|
||||
local meths = helpers.meths
|
||||
local missing_provider = helpers.missing_provider
|
||||
local write_file = helpers.write_file
|
||||
|
||||
do
|
||||
clear()
|
||||
@@ -90,3 +92,11 @@ describe(':rubydo command', function()
|
||||
eq(false, curbufmeths.get_option('modified'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('ruby provider', function()
|
||||
it('RPC call to expand("<afile>") during BufDelete #5245 #5617', function()
|
||||
command([=[autocmd BufDelete * ruby VIM::evaluate('expand("<afile>")')]=])
|
||||
feed_command('help help')
|
||||
eq(2, eval('1+1')) -- Still alive?
|
||||
end)
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user