patch 9.0.0221: accessing freed memory if compiling nested function fails
Problem: Accessing freed memory if compiling nested function fails. Solution: Mess up the variable name so that it won't be found.
This commit is contained in:
@ -911,6 +911,18 @@ def Test_nested_function()
|
|||||||
v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: burp', 3)
|
v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: burp', 3)
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def Test_nested_function_fails()
|
||||||
|
var lines =<< trim END
|
||||||
|
def T()
|
||||||
|
def Func(g: string):string
|
||||||
|
enddef
|
||||||
|
Func()
|
||||||
|
enddef
|
||||||
|
silent! defcompile
|
||||||
|
END
|
||||||
|
v9.CheckScriptFailure(lines, 'E1069:')
|
||||||
|
enddef
|
||||||
|
|
||||||
def Test_not_nested_function()
|
def Test_not_nested_function()
|
||||||
echo printf('%d',
|
echo printf('%d',
|
||||||
function('len')('xxx'))
|
function('len')('xxx'))
|
||||||
|
|||||||
@ -735,6 +735,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
221,
|
||||||
/**/
|
/**/
|
||||||
220,
|
220,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
@ -830,6 +830,7 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx, garray_T *lines_to_free)
|
|||||||
int r = FAIL;
|
int r = FAIL;
|
||||||
compiletype_T compile_type;
|
compiletype_T compile_type;
|
||||||
isn_T *funcref_isn = NULL;
|
isn_T *funcref_isn = NULL;
|
||||||
|
lvar_T *lvar = NULL;
|
||||||
|
|
||||||
if (eap->forceit)
|
if (eap->forceit)
|
||||||
{
|
{
|
||||||
@ -936,9 +937,8 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx, garray_T *lines_to_free)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Define a local variable for the function reference.
|
// Define a local variable for the function reference.
|
||||||
lvar_T *lvar = reserve_local(cctx, func_name, name_end - name_start,
|
lvar = reserve_local(cctx, func_name, name_end - name_start,
|
||||||
TRUE, ufunc->uf_func_type);
|
TRUE, ufunc->uf_func_type);
|
||||||
|
|
||||||
if (lvar == NULL)
|
if (lvar == NULL)
|
||||||
goto theend;
|
goto theend;
|
||||||
if (generate_FUNCREF(cctx, ufunc, &funcref_isn) == FAIL)
|
if (generate_FUNCREF(cctx, ufunc, &funcref_isn) == FAIL)
|
||||||
@ -957,6 +957,9 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx, garray_T *lines_to_free)
|
|||||||
&& compile_def_function(ufunc, TRUE, compile_type, cctx) == FAIL)
|
&& compile_def_function(ufunc, TRUE, compile_type, cctx) == FAIL)
|
||||||
{
|
{
|
||||||
func_ptr_unref(ufunc);
|
func_ptr_unref(ufunc);
|
||||||
|
if (lvar != NULL)
|
||||||
|
// Now the local variable can't be used.
|
||||||
|
*lvar->lv_name = '/'; // impossible value
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user