0
0
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:
Bram Moolenaar 2010-05-28 22:06:46 +02:00
parent 04fa5427b8
commit bc42c1e427
3 changed files with 18 additions and 8 deletions

View File

@ -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;
} }

View File

@ -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
---*--- ---*---

View File

@ -1,4 +1,4 @@
xxx4asdf fail nop ok 9 xxx4asdf fail nop ok 9 333
XX111XX XX111XX
---222--- ---222---
1. one 1. one