]> granicus.if.org Git - vim/commitdiff
patch 8.2.0098: exe stack length can be wrong without being detected v8.2.0098
authorBram Moolenaar <Bram@vim.org>
Tue, 7 Jan 2020 19:59:34 +0000 (20:59 +0100)
committerBram Moolenaar <Bram@vim.org>
Tue, 7 Jan 2020 19:59:34 +0000 (20:59 +0100)
Problem:    Exe stack length can be wrong without being detected.
Solution:   Add a check when ABORT_ON_INTERNAL_ERROR is defined.

src/autocmd.c
src/buffer.c
src/ex_docmd.c
src/macros.h
src/main.c
src/map.c
src/scriptfile.c
src/spellfile.c
src/userfunc.c
src/version.c

index 983a155c60fd9111ebbfd0443534d4af428758ee..13aa065ec822fcfc48fac3dd3a78b7f5bddbba93 100644 (file)
@@ -1827,6 +1827,7 @@ apply_autocmds_group(
     int                did_save_redobuff = FALSE;
     save_redo_T        save_redo;
     int                save_KeyTyped = KeyTyped;
+    ESTACK_CHECK_DECLARATION
 
     /*
      * Quickly return if there are no autocommands for this event or
@@ -2021,6 +2022,7 @@ apply_autocmds_group(
 
     // name and lnum are filled in later
     estack_push(ETYPE_AUCMD, NULL, 0);
+    ESTACK_CHECK_SETUP
 
 #ifdef FEAT_EVAL
     save_current_sctx = current_sctx;
@@ -2124,6 +2126,7 @@ apply_autocmds_group(
     filechangeshell_busy = FALSE;
     autocmd_nested = save_autocmd_nested;
     vim_free(SOURCING_NAME);
+    ESTACK_CHECK_NOW
     estack_pop();
     vim_free(autocmd_fname);
     autocmd_fname = save_autocmd_fname;
index 0a68d484e500b8074b2f4b4140fe197713e3be05..f56ff0b6259bc639e86ae3237ebf623076888ae6 100644 (file)
@@ -5287,6 +5287,7 @@ chk_modeline(
 #ifdef FEAT_EVAL
     sctx_T     save_current_sctx;
 #endif
+    ESTACK_CHECK_DECLARATION
 
     prev = -1;
     for (s = ml_get(lnum); *s != NUL; ++s)
@@ -5330,6 +5331,7 @@ chk_modeline(
 
        // prepare for emsg()
        estack_push(ETYPE_MODELINE, (char_u *)"modelines", lnum);
+       ESTACK_CHECK_SETUP
 
        end = FALSE;
        while (end == FALSE)
@@ -5390,6 +5392,7 @@ chk_modeline(
            s = e + 1;                  // advance to next part
        }
 
+       ESTACK_CHECK_NOW
        estack_pop();
        vim_free(linecopy);
     }
index de8fb49617d867f070450dcb626085356c0773e9..e11ad08d43132828e76dfb793b1965bcad2e64b2 100644 (file)
@@ -645,6 +645,7 @@ do_cmdline(
 # define cmd_cookie cookie
 #endif
     static int call_depth = 0;         // recursiveness
+    ESTACK_CHECK_DECLARATION
 
 #ifdef FEAT_EVAL
     // For every pair of do_cmdline()/do_one_cmd() calls, use an extra memory
@@ -1260,6 +1261,7 @@ do_cmdline(
 
            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'
@@ -1284,6 +1286,7 @@ do_cmdline(
                vim_free(p);
            }
            vim_free(SOURCING_NAME);
+           ESTACK_CHECK_NOW
            estack_pop();
        }
 
index ca7e4b5d0b6a0fec0c8820b001eb12c797108ef2..455705ca4f581a1bdadc401e0a1424a6dfbc0ac9 100644 (file)
 #else
 # define ERROR_IF_POPUP_WINDOW 0
 #endif
+
+
+#ifdef ABORT_ON_INTERNAL_ERROR
+# define ESTACK_CHECK_DECLARATION int estack_len_before;
+# define ESTACK_CHECK_SETUP estack_len_before = exestack.ga_len;
+# define ESTACK_CHECK_NOW if (estack_len_before != exestack.ga_len) \
+       siemsg("Exestack length expected: %d, actual: %d", estack_len_before, exestack.ga_len);
+#else
+# define ESTACK_CHECK_DECLARATION
+# define ESTACK_CHECK_SETUP
+# define ESTACK_CHECK_NOW
+#endif
index 51b8970b9bb34f8ec14135032edc2a80216758ca..117c2072e633a2297ee425813c647fe270452625 100644 (file)
@@ -3086,16 +3086,19 @@ exe_pre_commands(mparm_T *parmp)
     char_u     **cmds = parmp->pre_commands;
     int                cnt = parmp->n_pre_commands;
     int                i;
+    ESTACK_CHECK_DECLARATION
 
     if (cnt > 0)
     {
        curwin->w_cursor.lnum = 0; // just in case..
        estack_push(ETYPE_ARGS, (char_u *)_("pre-vimrc command line"), 0);
+       ESTACK_CHECK_SETUP
 # ifdef FEAT_EVAL
        current_sctx.sc_sid = SID_CMDARG;
 # endif
        for (i = 0; i < cnt; ++i)
            do_cmdline_cmd(cmds[i]);
+       ESTACK_CHECK_NOW
        estack_pop();
 # ifdef FEAT_EVAL
        current_sctx.sc_sid = 0;
@@ -3111,6 +3114,7 @@ exe_pre_commands(mparm_T *parmp)
 exe_commands(mparm_T *parmp)
 {
     int                i;
+    ESTACK_CHECK_DECLARATION
 
     /*
      * We start commands on line 0, make "vim +/pat file" match a
@@ -3121,6 +3125,7 @@ exe_commands(mparm_T *parmp)
     if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1)
        curwin->w_cursor.lnum = 0;
     estack_push(ETYPE_ARGS, (char_u *)"command line", 0);
+    ESTACK_CHECK_SETUP
 #ifdef FEAT_EVAL
     current_sctx.sc_sid = SID_CARG;
     current_sctx.sc_seq = 0;
@@ -3131,6 +3136,7 @@ exe_commands(mparm_T *parmp)
        if (parmp->cmds_tofree[i])
            vim_free(parmp->commands[i]);
     }
+    ESTACK_CHECK_NOW
     estack_pop();
 #ifdef FEAT_EVAL
     current_sctx.sc_sid = 0;
@@ -3340,12 +3346,14 @@ process_env(
 #ifdef FEAT_EVAL
     sctx_T     save_current_sctx;
 #endif
+    ESTACK_CHECK_DECLARATION
 
     if ((initstr = mch_getenv(env)) != NULL && *initstr != NUL)
     {
        if (is_viminit)
            vimrc_found(NULL, NULL);
        estack_push(ETYPE_ENV, env, 0);
+       ESTACK_CHECK_SETUP
 #ifdef FEAT_EVAL
        save_current_sctx = current_sctx;
        current_sctx.sc_sid = SID_ENV;
@@ -3355,6 +3363,7 @@ process_env(
 #endif
        do_cmdline_cmd(initstr);
 
+       ESTACK_CHECK_NOW
        estack_pop();
 #ifdef FEAT_EVAL
        current_sctx = save_current_sctx;
index 451190d445fcf76dfbca8f03c2d9ec43c4c21b36..31c288201dbaf75a88b95501a08ff86fcf475f48 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -1918,10 +1918,12 @@ check_map_keycodes(void)
     int                abbr;
     int                hash;
     buf_T      *bp;
+    ESTACK_CHECK_DECLARATION
 
     validate_maphash();
     // avoids giving error messages
     estack_push(ETYPE_INTERNAL, (char_u *)"mappings", 0);
+    ESTACK_CHECK_SETUP
 
     // Do this once for each buffer, and then once for global
     // mappings/abbreviations with bp == NULL
@@ -1978,6 +1980,7 @@ check_map_keycodes(void)
        if (bp == NULL)
            break;
     }
+    ESTACK_CHECK_NOW
     estack_pop();
 }
 
index 38516c360a61d4212e4ba53d9d62d87c99a3635a..a1755416b42b364a806e1281d79c81034e7b6895 100644 (file)
@@ -1099,6 +1099,7 @@ do_source(
     proftime_T             wait_start;
 #endif
     int                            trigger_source_post = FALSE;
+    ESTACK_CHECK_DECLARATION
 
     p = expand_env_save(fname);
     if (p == NULL)
@@ -1216,6 +1217,7 @@ do_source(
 
     // Keep the sourcing name/lnum, for recursive calls.
     estack_push(ETYPE_SCRIPT, fname_exp, 0);
+    ESTACK_CHECK_SETUP
 
 #ifdef STARTUPTIME
     if (time_fd != NULL)
@@ -1355,6 +1357,7 @@ do_source(
 
     if (got_int)
        emsg(_(e_interr));
+    ESTACK_CHECK_NOW
     estack_pop();
     if (p_verbose > 1)
     {
index fa450f33ddeb14a07ad05942d39c5f0a1b6c1848..c3e53b330bf07b915fa5d62431408ae6567df97c 100644 (file)
@@ -353,6 +353,7 @@ spell_load_file(
     int                c = 0;
     int                res;
     int                did_estack_push = FALSE;
+    ESTACK_CHECK_DECLARATION
 
     fd = mch_fopen((char *)fname, "r");
     if (fd == NULL)
@@ -393,6 +394,7 @@ spell_load_file(
 
     // Set sourcing_name, so that error messages mention the file name.
     estack_push(ETYPE_SPELL, fname, 0);
+    ESTACK_CHECK_SETUP
     did_estack_push = TRUE;
 
     /*
@@ -581,7 +583,10 @@ endOK:
     if (fd != NULL)
        fclose(fd);
     if (did_estack_push)
+    {
+       ESTACK_CHECK_NOW
        estack_pop();
+    }
 
     return lp;
 }
index 95862fe875f56791f66faaa20d544197021fc60e..29e0fac050e85a4dbf1385616205cb49fd628f30 100644 (file)
@@ -793,6 +793,7 @@ call_user_func(
     proftime_T call_start;
     int                started_profiling = FALSE;
 #endif
+    ESTACK_CHECK_DECLARATION
 
     // If depth of calling is getting too high, don't execute the function
     if (depth >= p_mfd)
@@ -969,6 +970,7 @@ call_user_func(
     }
 
     estack_push_ufunc(ETYPE_UFUNC, fp, 1);
+    ESTACK_CHECK_SETUP
     if (p_verbose >= 12)
     {
        ++no_wait_return;
@@ -1115,6 +1117,7 @@ call_user_func(
        --no_wait_return;
     }
 
+    ESTACK_CHECK_NOW
     estack_pop();
     current_sctx = save_current_sctx;
 #ifdef FEAT_PROFILE
index b476e25a4c8274afba7680c903e77ff1d269a3f9..c466c29b243215fbe4cef89824d4bf003063f4d3 100644 (file)
@@ -742,6 +742,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    98,
 /**/
     97,
 /**/