Mercurial > vim
comparison src/eval.c @ 2179:cd6e6876308e v7.2.440
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)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Fri, 28 May 2010 22:06:46 +0200 |
parents | cf8f86128f4c |
children | 0c1e413c32f1 |
comparison
equal
deleted
inserted
replaced
2177:ea7c2d89b76b | 2179:cd6e6876308e |
---|---|
462 #endif | 462 #endif |
463 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); | 463 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); |
464 static int find_internal_func __ARGS((char_u *name)); | 464 static int find_internal_func __ARGS((char_u *name)); |
465 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); | 465 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); |
466 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)); | 466 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)); |
467 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)); | 467 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)); |
468 static void emsg_funcname __ARGS((char *ermsg, char_u *name)); | 468 static void emsg_funcname __ARGS((char *ermsg, char_u *name)); |
469 static int non_zero_arg __ARGS((typval_T *argvars)); | 469 static int non_zero_arg __ARGS((typval_T *argvars)); |
470 | 470 |
471 #ifdef FEAT_FLOAT | 471 #ifdef FEAT_FLOAT |
472 static void f_abs __ARGS((typval_T *argvars, typval_T *rettv)); | 472 static void f_abs __ARGS((typval_T *argvars, typval_T *rettv)); |
7995 * Call a function with its resolved parameters | 7995 * Call a function with its resolved parameters |
7996 * Return OK when the function can't be called, FAIL otherwise. | 7996 * Return OK when the function can't be called, FAIL otherwise. |
7997 * Also returns OK when an error was encountered while executing the function. | 7997 * Also returns OK when an error was encountered while executing the function. |
7998 */ | 7998 */ |
7999 static int | 7999 static int |
8000 call_func(name, len, rettv, argcount, argvars, firstline, lastline, | 8000 call_func(func_name, len, rettv, argcount, argvars, firstline, lastline, |
8001 doesrange, evaluate, selfdict) | 8001 doesrange, evaluate, selfdict) |
8002 char_u *name; /* name of the function */ | 8002 char_u *func_name; /* name of the function */ |
8003 int len; /* length of "name" */ | 8003 int len; /* length of "name" */ |
8004 typval_T *rettv; /* return value goes here */ | 8004 typval_T *rettv; /* return value goes here */ |
8005 int argcount; /* number of "argvars" */ | 8005 int argcount; /* number of "argvars" */ |
8006 typval_T *argvars; /* vars for arguments, must have "argcount" | 8006 typval_T *argvars; /* vars for arguments, must have "argcount" |
8007 PLUS ONE elements! */ | 8007 PLUS ONE elements! */ |
8021 #define ERROR_OTHER 6 | 8021 #define ERROR_OTHER 6 |
8022 int error = ERROR_NONE; | 8022 int error = ERROR_NONE; |
8023 int i; | 8023 int i; |
8024 int llen; | 8024 int llen; |
8025 ufunc_T *fp; | 8025 ufunc_T *fp; |
8026 int cc; | |
8027 #define FLEN_FIXED 40 | 8026 #define FLEN_FIXED 40 |
8028 char_u fname_buf[FLEN_FIXED + 1]; | 8027 char_u fname_buf[FLEN_FIXED + 1]; |
8029 char_u *fname; | 8028 char_u *fname; |
8029 char_u *name; | |
8030 | |
8031 /* Make a copy of the name, if it comes from a funcref variable it could | |
8032 * be changed or deleted in the called function. */ | |
8033 name = vim_strnsave(func_name, len); | |
8034 if (name == NULL) | |
8035 return ret; | |
8030 | 8036 |
8031 /* | 8037 /* |
8032 * In a script change <SID>name() and s:name() to K_SNR 123_name(). | 8038 * In a script change <SID>name() and s:name() to K_SNR 123_name(). |
8033 * Change <SNR>123_name() to K_SNR 123_name(). | 8039 * Change <SNR>123_name() to K_SNR 123_name(). |
8034 * Use fname_buf[] when it fits, otherwise allocate memory (slow). | 8040 * Use fname_buf[] when it fits, otherwise allocate memory (slow). |
8035 */ | 8041 */ |
8036 cc = name[len]; | |
8037 name[len] = NUL; | |
8038 llen = eval_fname_script(name); | 8042 llen = eval_fname_script(name); |
8039 if (llen > 0) | 8043 if (llen > 0) |
8040 { | 8044 { |
8041 fname_buf[0] = K_SPECIAL; | 8045 fname_buf[0] = K_SPECIAL; |
8042 fname_buf[1] = KS_EXTRA; | 8046 fname_buf[1] = KS_EXTRA; |
8203 name); | 8207 name); |
8204 break; | 8208 break; |
8205 } | 8209 } |
8206 } | 8210 } |
8207 | 8211 |
8208 name[len] = cc; | |
8209 if (fname != name && fname != fname_buf) | 8212 if (fname != name && fname != fname_buf) |
8210 vim_free(fname); | 8213 vim_free(fname); |
8214 vim_free(name); | |
8211 | 8215 |
8212 return ret; | 8216 return ret; |
8213 } | 8217 } |
8214 | 8218 |
8215 /* | 8219 /* |