mirror of
https://github.com/vim/vim.git
synced 2025-09-27 04:14:06 -04:00
patch 9.0.0577: buffer underflow with unexpected :finally
Problem: Buffer underflow with unexpected :finally. Solution: Check CSF_TRY can be found.
This commit is contained in:
@@ -1935,23 +1935,23 @@ ex_finally(exarg_T *eap)
|
|||||||
if (cmdmod_error(FALSE))
|
if (cmdmod_error(FALSE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0)
|
for (idx = cstack->cs_idx; idx >= 0; --idx)
|
||||||
eap->errmsg = _(e_finally_without_try);
|
if (cstack->cs_flags[idx] & CSF_TRY)
|
||||||
else
|
break;
|
||||||
|
if (cstack->cs_trylevel <= 0 || idx < 0)
|
||||||
{
|
{
|
||||||
|
eap->errmsg = _(e_finally_without_try);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY))
|
if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY))
|
||||||
{
|
{
|
||||||
eap->errmsg = get_end_emsg(cstack);
|
eap->errmsg = get_end_emsg(cstack);
|
||||||
for (idx = cstack->cs_idx - 1; idx > 0; --idx)
|
|
||||||
if (cstack->cs_flags[idx] & CSF_TRY)
|
|
||||||
break;
|
|
||||||
// Make this error pending, so that the commands in the following
|
// Make this error pending, so that the commands in the following
|
||||||
// finally clause can be executed. This overrules also a pending
|
// finally clause can be executed. This overrules also a pending
|
||||||
// ":continue", ":break", ":return", or ":finish".
|
// ":continue", ":break", ":return", or ":finish".
|
||||||
pending = CSTP_ERROR;
|
pending = CSTP_ERROR;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
idx = cstack->cs_idx;
|
|
||||||
|
|
||||||
if (cstack->cs_flags[idx] & CSF_FINALLY)
|
if (cstack->cs_flags[idx] & CSF_FINALLY)
|
||||||
{
|
{
|
||||||
@@ -2057,7 +2057,6 @@ ex_finally(exarg_T *eap)
|
|||||||
*/
|
*/
|
||||||
cstack->cs_lflags |= CSL_HAD_FINA;
|
cstack->cs_lflags |= CSL_HAD_FINA;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2076,10 +2075,15 @@ ex_endtry(exarg_T *eap)
|
|||||||
if (cmdmod_error(FALSE))
|
if (cmdmod_error(FALSE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0)
|
for (idx = cstack->cs_idx; idx >= 0; --idx)
|
||||||
eap->errmsg = _(e_endtry_without_try);
|
if (cstack->cs_flags[idx] & CSF_TRY)
|
||||||
else
|
break;
|
||||||
|
if (cstack->cs_trylevel <= 0 || idx < 0)
|
||||||
{
|
{
|
||||||
|
eap->errmsg = _(e_endtry_without_try);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't do something after an error, interrupt or throw in the try
|
* Don't do something after an error, interrupt or throw in the try
|
||||||
* block, catch clause, or finally clause preceding this ":endtry" or
|
* block, catch clause, or finally clause preceding this ":endtry" or
|
||||||
@@ -2099,10 +2103,6 @@ ex_endtry(exarg_T *eap)
|
|||||||
eap->errmsg = get_end_emsg(cstack);
|
eap->errmsg = get_end_emsg(cstack);
|
||||||
|
|
||||||
// Find the matching ":try" and report what's missing.
|
// Find the matching ":try" and report what's missing.
|
||||||
idx = cstack->cs_idx;
|
|
||||||
do
|
|
||||||
--idx;
|
|
||||||
while (idx > 0 && !(cstack->cs_flags[idx] & CSF_TRY));
|
|
||||||
rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
|
rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
|
||||||
&cstack->cs_looplevel);
|
&cstack->cs_looplevel);
|
||||||
skip = TRUE;
|
skip = TRUE;
|
||||||
@@ -2151,8 +2151,7 @@ ex_endtry(exarg_T *eap)
|
|||||||
// on an interrupt or error not converted to an exception or when
|
// on an interrupt or error not converted to an exception or when
|
||||||
// a ":break", ":continue", ":return", or ":finish" is pending. These
|
// a ":break", ":continue", ":return", or ":finish" is pending. These
|
||||||
// actions are carried out immediately.
|
// actions are carried out immediately.
|
||||||
if ((rethrow || (!skip
|
if ((rethrow || (!skip && !(cstack->cs_flags[idx] & CSF_FINALLY)
|
||||||
&& !(cstack->cs_flags[idx] & CSF_FINALLY)
|
|
||||||
&& !cstack->cs_pending[idx]))
|
&& !cstack->cs_pending[idx]))
|
||||||
&& dbg_check_skipped(eap))
|
&& dbg_check_skipped(eap))
|
||||||
{
|
{
|
||||||
@@ -2199,8 +2198,7 @@ ex_endtry(exarg_T *eap)
|
|||||||
*/
|
*/
|
||||||
(void)cleanup_conditionals(cstack, CSF_TRY | CSF_SILENT, TRUE);
|
(void)cleanup_conditionals(cstack, CSF_TRY | CSF_SILENT, TRUE);
|
||||||
|
|
||||||
if (cstack->cs_idx >= 0
|
if (cstack->cs_idx >= 0 && (cstack->cs_flags[cstack->cs_idx] & CSF_TRY))
|
||||||
&& (cstack->cs_flags[cstack->cs_idx] & CSF_TRY))
|
|
||||||
leave_block(cstack);
|
leave_block(cstack);
|
||||||
--cstack->cs_trylevel;
|
--cstack->cs_trylevel;
|
||||||
|
|
||||||
@@ -2254,7 +2252,6 @@ ex_endtry(exarg_T *eap)
|
|||||||
if (rethrow)
|
if (rethrow)
|
||||||
// Rethrow the current exception (within this cstack).
|
// Rethrow the current exception (within this cstack).
|
||||||
do_throw(cstack);
|
do_throw(cstack);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
source check.vim
|
source check.vim
|
||||||
source shared.vim
|
source shared.vim
|
||||||
|
import './vim9.vim' as v9
|
||||||
|
|
||||||
"-------------------------------------------------------------------------------
|
"-------------------------------------------------------------------------------
|
||||||
" Test environment {{{1
|
" Test environment {{{1
|
||||||
@@ -2008,6 +2009,27 @@ func Test_try_catch_errors()
|
|||||||
call assert_fails('try | for i in range(5) | endif | endtry', 'E580:')
|
call assert_fails('try | for i in range(5) | endif | endtry', 'E580:')
|
||||||
call assert_fails('try | while v:true | endtry', 'E170:')
|
call assert_fails('try | while v:true | endtry', 'E170:')
|
||||||
call assert_fails('try | if v:true | endtry', 'E171:')
|
call assert_fails('try | if v:true | endtry', 'E171:')
|
||||||
|
|
||||||
|
" this was using a negative index in cstack[]
|
||||||
|
let lines =<< trim END
|
||||||
|
try
|
||||||
|
for
|
||||||
|
if
|
||||||
|
endwhile
|
||||||
|
if
|
||||||
|
finally
|
||||||
|
END
|
||||||
|
call v9.CheckScriptFailure(lines, 'E690:')
|
||||||
|
|
||||||
|
let lines =<< trim END
|
||||||
|
try
|
||||||
|
for
|
||||||
|
if
|
||||||
|
endwhile
|
||||||
|
if
|
||||||
|
endtry
|
||||||
|
END
|
||||||
|
call v9.CheckScriptFailure(lines, 'E690:')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
" Test for verbose messages with :try :catch, and :finally {{{1
|
" Test for verbose messages with :try :catch, and :finally {{{1
|
||||||
|
@@ -699,6 +699,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 */
|
||||||
|
/**/
|
||||||
|
577,
|
||||||
/**/
|
/**/
|
||||||
576,
|
576,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user