mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
updated for version 7.2.440
Problem: Calling a function through a funcref, where the function deletes the funcref, leads to an invalid memory access. Solution: Make a copy of the function name. (Lech Lorens)
This commit is contained in:
parent
04fa5427b8
commit
bc42c1e427
18
src/eval.c
18
src/eval.c
@ -464,7 +464,7 @@ static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
|
|||||||
static int find_internal_func __ARGS((char_u *name));
|
static int find_internal_func __ARGS((char_u *name));
|
||||||
static char_u *deref_func_name __ARGS((char_u *name, int *lenp));
|
static char_u *deref_func_name __ARGS((char_u *name, int *lenp));
|
||||||
static int get_func_tv __ARGS((char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict));
|
static int get_func_tv __ARGS((char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict));
|
||||||
static int call_func __ARGS((char_u *name, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict));
|
static int call_func __ARGS((char_u *func_name, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict));
|
||||||
static void emsg_funcname __ARGS((char *ermsg, char_u *name));
|
static void emsg_funcname __ARGS((char *ermsg, char_u *name));
|
||||||
static int non_zero_arg __ARGS((typval_T *argvars));
|
static int non_zero_arg __ARGS((typval_T *argvars));
|
||||||
|
|
||||||
@ -8029,9 +8029,9 @@ get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange,
|
|||||||
* Also returns OK when an error was encountered while executing the function.
|
* Also returns OK when an error was encountered while executing the function.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
call_func(name, len, rettv, argcount, argvars, firstline, lastline,
|
call_func(func_name, len, rettv, argcount, argvars, firstline, lastline,
|
||||||
doesrange, evaluate, selfdict)
|
doesrange, evaluate, selfdict)
|
||||||
char_u *name; /* name of the function */
|
char_u *func_name; /* name of the function */
|
||||||
int len; /* length of "name" */
|
int len; /* length of "name" */
|
||||||
typval_T *rettv; /* return value goes here */
|
typval_T *rettv; /* return value goes here */
|
||||||
int argcount; /* number of "argvars" */
|
int argcount; /* number of "argvars" */
|
||||||
@ -8055,18 +8055,22 @@ call_func(name, len, rettv, argcount, argvars, firstline, lastline,
|
|||||||
int i;
|
int i;
|
||||||
int llen;
|
int llen;
|
||||||
ufunc_T *fp;
|
ufunc_T *fp;
|
||||||
int cc;
|
|
||||||
#define FLEN_FIXED 40
|
#define FLEN_FIXED 40
|
||||||
char_u fname_buf[FLEN_FIXED + 1];
|
char_u fname_buf[FLEN_FIXED + 1];
|
||||||
char_u *fname;
|
char_u *fname;
|
||||||
|
char_u *name;
|
||||||
|
|
||||||
|
/* Make a copy of the name, if it comes from a funcref variable it could
|
||||||
|
* be changed or deleted in the called function. */
|
||||||
|
name = vim_strnsave(func_name, len);
|
||||||
|
if (name == NULL)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In a script change <SID>name() and s:name() to K_SNR 123_name().
|
* In a script change <SID>name() and s:name() to K_SNR 123_name().
|
||||||
* Change <SNR>123_name() to K_SNR 123_name().
|
* Change <SNR>123_name() to K_SNR 123_name().
|
||||||
* Use fname_buf[] when it fits, otherwise allocate memory (slow).
|
* Use fname_buf[] when it fits, otherwise allocate memory (slow).
|
||||||
*/
|
*/
|
||||||
cc = name[len];
|
|
||||||
name[len] = NUL;
|
|
||||||
llen = eval_fname_script(name);
|
llen = eval_fname_script(name);
|
||||||
if (llen > 0)
|
if (llen > 0)
|
||||||
{
|
{
|
||||||
@ -8237,9 +8241,9 @@ call_func(name, len, rettv, argcount, argvars, firstline, lastline,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
name[len] = cc;
|
|
||||||
if (fname != name && fname != fname_buf)
|
if (fname != name && fname != fname_buf)
|
||||||
vim_free(fname);
|
vim_free(fname);
|
||||||
|
vim_free(name);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,11 @@ STARTTEST
|
|||||||
: let g:counter = 0
|
: let g:counter = 0
|
||||||
: return ''
|
: return ''
|
||||||
:endfunc
|
:endfunc
|
||||||
|
:func FuncWithRef(a)
|
||||||
|
: unlet g:FuncRef
|
||||||
|
: return a:a
|
||||||
|
:endfunc
|
||||||
|
:let g:FuncRef=function("FuncWithRef")
|
||||||
:let counter = 0
|
:let counter = 0
|
||||||
:inoremap <expr> ( ListItem()
|
:inoremap <expr> ( ListItem()
|
||||||
:inoremap <expr> [ ListReset()
|
:inoremap <expr> [ ListReset()
|
||||||
@ -47,6 +52,7 @@ C=Table("xxx", 4, "asdf")
|
|||||||
=retval
|
=retval
|
||||||
=Compute(45, 5, "retval")
|
=Compute(45, 5, "retval")
|
||||||
=retval
|
=retval
|
||||||
|
=g:FuncRef(333)
|
||||||
|
|
||||||
XX+-XX
|
XX+-XX
|
||||||
---*---
|
---*---
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
xxx4asdf fail nop ok 9
|
xxx4asdf fail nop ok 9 333
|
||||||
XX111XX
|
XX111XX
|
||||||
---222---
|
---222---
|
||||||
1. one
|
1. one
|
||||||
|
Loading…
x
Reference in New Issue
Block a user