vim-patch:8.2.0098: exe stack length can be wrong without being detected (#37136)

Problem:    Exe stack length can be wrong without being detected.
Solution:   Add a check when ABORT_ON_INTERNAL_ERROR is defined.

e31ee86859

vim-patch:8.2.3262: build failure when ABORT_ON_INTERNAL_ERROR is defined

Port patch 9.0.1454 for "make formatc".

Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
Jan Edmund Lazo
2025-12-28 01:26:29 -05:00
committed by GitHub
parent 444e1ffe3e
commit c81f7aeee2
8 changed files with 43 additions and 0 deletions

View File

@@ -1669,6 +1669,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
bool did_save_redobuff = false;
save_redo_T save_redo;
const bool save_KeyTyped = KeyTyped;
ESTACK_CHECK_DECLARATION;
// Quickly return if there are no autocommands for this event or
// autocommands are blocked.
@@ -1853,6 +1854,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
// name and lnum are filled in later
estack_push(ETYPE_AUCMD, NULL, 0);
ESTACK_CHECK_SETUP;
const sctx_T save_current_sctx = current_sctx;
@@ -1962,6 +1964,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
filechangeshell_busy = false;
autocmd_nested = save_autocmd_nested;
xfree(SOURCING_NAME);
ESTACK_CHECK_NOW;
estack_pop();
xfree(afile_orig);
xfree(autocmd_fname);

View File

@@ -3788,6 +3788,7 @@ static int chk_modeline(linenr_T lnum, int flags)
{
char *e;
int retval = OK;
ESTACK_CHECK_DECLARATION;
int prev = -1;
char *s = ml_get(lnum);
@@ -3843,6 +3844,7 @@ static int chk_modeline(linenr_T lnum, int flags)
// prepare for emsg()
estack_push(ETYPE_MODELINE, "modelines", lnum);
ESTACK_CHECK_SETUP;
bool end = false;
while (end == false) {
@@ -3899,6 +3901,7 @@ static int chk_modeline(linenr_T lnum, int flags)
// careful not to go off the end
}
ESTACK_CHECK_NOW;
estack_pop();
xfree(linecopy);

View File

@@ -1010,6 +1010,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
bool started_profiling = false;
bool did_save_redo = false;
save_redo_T save_redo;
ESTACK_CHECK_DECLARATION;
// If depth of calling is getting too high, don't execute the function
if (depth >= p_mfd) {
@@ -1181,6 +1182,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
}
estack_push_ufunc(fp, 1);
ESTACK_CHECK_SETUP;
if (p_verbose >= 12) {
no_wait_return++;
verbose_enter_scroll();
@@ -1332,6 +1334,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
no_wait_return--;
}
ESTACK_CHECK_NOW;
estack_pop();
current_sctx = save_current_sctx;
if (do_profiling_yes) {

View File

@@ -964,6 +964,7 @@ void handle_did_throw(void)
assert(current_exception != NULL);
char *p = NULL;
msglist_T *messages = NULL;
ESTACK_CHECK_DECLARATION;
// If the uncaught exception is a user exception, report it as an
// error. If it is an error exception, display the saved error
@@ -985,6 +986,7 @@ void handle_did_throw(void)
}
estack_push(ETYPE_EXCEPT, current_exception->throw_name, current_exception->throw_lnum);
ESTACK_CHECK_SETUP;
current_exception->throw_name = NULL;
discard_current_exception(); // uses IObuff if 'verbose'
@@ -1009,6 +1011,7 @@ void handle_did_throw(void)
xfree(p);
}
xfree(SOURCING_NAME);
ESTACK_CHECK_NOW;
estack_pop();
}

View File

@@ -1918,6 +1918,7 @@ static void exe_pre_commands(mparm_T *parmp)
{
char **cmds = parmp->pre_commands;
int cnt = parmp->n_pre_commands;
ESTACK_CHECK_DECLARATION;
if (cnt <= 0) {
return;
@@ -1925,10 +1926,12 @@ static void exe_pre_commands(mparm_T *parmp)
curwin->w_cursor.lnum = 0; // just in case..
estack_push(ETYPE_ARGS, _("pre-vimrc command line"), 0);
ESTACK_CHECK_SETUP;
current_sctx.sc_sid = SID_CMDARG;
for (int i = 0; i < cnt; i++) {
do_cmdline_cmd(cmds[i]);
}
ESTACK_CHECK_NOW;
estack_pop();
current_sctx.sc_sid = 0;
TIME_MSG("--cmd commands");
@@ -1937,6 +1940,8 @@ static void exe_pre_commands(mparm_T *parmp)
// Execute "+", "-c" and "-S" arguments.
static void exe_commands(mparm_T *parmp)
{
ESTACK_CHECK_DECLARATION;
// We start commands on line 0, make "vim +/pat file" match a
// pattern on line 1. But don't move the cursor when an autocommand
// with g`" was used.
@@ -1945,6 +1950,7 @@ static void exe_commands(mparm_T *parmp)
curwin->w_cursor.lnum = 0;
}
estack_push(ETYPE_ARGS, "command line", 0);
ESTACK_CHECK_SETUP;
current_sctx.sc_sid = SID_CARG;
current_sctx.sc_seq = 0;
for (int i = 0; i < parmp->n_commands; i++) {
@@ -1953,6 +1959,7 @@ static void exe_commands(mparm_T *parmp)
xfree(parmp->commands[i]);
}
}
ESTACK_CHECK_NOW;
estack_pop();
current_sctx.sc_sid = 0;
if (curwin->w_cursor.lnum == 0) {
@@ -2149,18 +2156,21 @@ static void source_startup_scripts(const mparm_T *const parmp)
static int execute_env(char *env)
FUNC_ATTR_NONNULL_ALL
{
ESTACK_CHECK_DECLARATION;
char *initstr = os_getenv(env);
if (initstr == NULL) {
return FAIL;
}
estack_push(ETYPE_ENV, env, 0);
ESTACK_CHECK_SETUP;
const sctx_T save_current_sctx = current_sctx;
current_sctx.sc_sid = SID_ENV;
current_sctx.sc_seq = 0;
current_sctx.sc_lnum = 0;
do_cmdline_cmd(initstr);
ESTACK_CHECK_NOW;
estack_pop();
current_sctx = save_current_sctx;

View File

@@ -2092,6 +2092,7 @@ static int do_source_ext(char *const fname, const bool check_other, const int is
scriptitem_T *si = NULL;
proftime_T wait_start;
bool trigger_source_post = false;
ESTACK_CHECK_DECLARATION;
CLEAR_FIELD(cookie);
char *fname_exp = NULL;
@@ -2255,6 +2256,7 @@ static int do_source_ext(char *const fname, const bool check_other, const int is
// Keep the sourcing name/lnum, for recursive calls.
estack_push(ETYPE_SCRIPT, si != NULL ? si->sn_name : fname_exp, 0);
ESTACK_CHECK_SETUP;
if (l_do_profiling == PROF_YES && si != NULL) {
bool forceit = false;
@@ -2316,6 +2318,7 @@ static int do_source_ext(char *const fname, const bool check_other, const int is
if (got_int) {
emsg(_(e_interr));
}
ESTACK_CHECK_NOW;
estack_pop();
if (p_verbose > 1) {
verbose_enter();

View File

@@ -45,4 +45,19 @@ enum {
DIP_DIRFILE = 0x200, ///< find both files and directories
};
#ifdef ABORT_ON_INTERNAL_ERROR
# define ESTACK_CHECK_DECLARATION int estack_len_before
# define ESTACK_CHECK_SETUP do { estack_len_before = exestack.ga_len; } while (0)
# define ESTACK_CHECK_NOW \
do { \
if (estack_len_before != exestack.ga_len) { \
siemsg("Exestack length expected: %d, actual: %d", estack_len_before, exestack.ga_len); \
} \
} while (0)
#else
# define ESTACK_CHECK_DECLARATION do {} while (0)
# define ESTACK_CHECK_SETUP do {} while (0)
# define ESTACK_CHECK_NOW do {} while (0)
#endif
#include "runtime.h.generated.h"

View File

@@ -608,6 +608,7 @@ slang_T *spell_load_file(char *fname, char *lang, slang_T *old_lp, bool silent)
slang_T *lp = NULL;
int res;
bool did_estack_push = false;
ESTACK_CHECK_DECLARATION;
FILE *fd = os_fopen(fname, "r");
if (fd == NULL) {
@@ -640,6 +641,7 @@ slang_T *spell_load_file(char *fname, char *lang, slang_T *old_lp, bool silent)
// Set sourcing_name, so that error messages mention the file name.
estack_push(ETYPE_SPELL, fname, 0);
ESTACK_CHECK_SETUP;
did_estack_push = true;
// <HEADER>: <fileID>
@@ -838,6 +840,7 @@ endOK:
fclose(fd);
}
if (did_estack_push) {
ESTACK_CHECK_NOW;
estack_pop();
}