To: vim_dev@googlegroups.com Subject: Patch 8.2.1539 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1539 Problem: Using invalid script ID causes a crash. Solution: Check the script ID to be valid. (closes #6804) Files: src/globals.h, src/evalvars.c, src/profiler.c, src/scriptfile.c, src/vim9compile.c, src/testdir/test_vim9_script.vim *** ../vim-8.2.1538/src/globals.h 2020-08-18 13:41:47.215350419 +0200 --- src/globals.h 2020-08-29 13:14:13.419717244 +0200 *************** *** 297,304 **** # endif EXTERN garray_T script_items INIT5(0, 0, sizeof(scriptitem_T *), 20, NULL); # define SCRIPT_ITEM(id) (((scriptitem_T **)script_items.ga_data)[(id) - 1]) ! # define SCRIPT_SV(id) (SCRIPT_ITEM(id)->sn_vars) ! # define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab) # define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j] --- 297,305 ---- # endif EXTERN garray_T script_items INIT5(0, 0, sizeof(scriptitem_T *), 20, NULL); # define SCRIPT_ITEM(id) (((scriptitem_T **)script_items.ga_data)[(id) - 1]) ! # define SCRIPT_ID_VALID(id) ((id) > 0 && (id) <= script_items.ga_len) ! # define SCRIPT_SV(id) (SCRIPT_ITEM(id)->sn_vars) ! # define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab) # define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j] *** ../vim-8.2.1538/src/evalvars.c 2020-08-27 21:33:06.978960755 +0200 --- src/evalvars.c 2020-08-29 13:16:02.267299403 +0200 *************** *** 524,530 **** static void list_script_vars(int *first) { ! if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) list_hashtable_vars(&SCRIPT_VARS(current_sctx.sc_sid), "s:", FALSE, first); } --- 524,530 ---- static void list_script_vars(int *first) { ! if (SCRIPT_ID_VALID(current_sctx.sc_sid)) list_hashtable_vars(&SCRIPT_VARS(current_sctx.sc_sid), "s:", FALSE, first); } *************** *** 2609,2615 **** { scid_T sid = current_sctx.sc_sid; ! if (sid > 0 && sid <= script_items.ga_len) return &SCRIPT_VARS(sid); return NULL; } --- 2609,2615 ---- { scid_T sid = current_sctx.sc_sid; ! if (SCRIPT_ID_VALID(sid)) return &SCRIPT_VARS(sid); return NULL; } *** ../vim-8.2.1538/src/profiler.c 2020-01-26 19:26:42.794068329 +0100 --- src/profiler.c 2020-08-29 13:17:47.206908233 +0200 *************** *** 761,767 **** { scriptitem_T *si; ! if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) { si = SCRIPT_ITEM(current_sctx.sc_sid); if (si->sn_prof_on && si->sn_pr_nest++ == 0) --- 761,767 ---- { scriptitem_T *si; ! if (SCRIPT_ID_VALID(current_sctx.sc_sid)) { si = SCRIPT_ITEM(current_sctx.sc_sid); if (si->sn_prof_on && si->sn_pr_nest++ == 0) *************** *** 778,784 **** { scriptitem_T *si; ! if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) { si = SCRIPT_ITEM(current_sctx.sc_sid); if (si->sn_prof_on && --si->sn_pr_nest == 0) --- 778,784 ---- { scriptitem_T *si; ! if (SCRIPT_ID_VALID(current_sctx.sc_sid)) { si = SCRIPT_ITEM(current_sctx.sc_sid); if (si->sn_prof_on && --si->sn_pr_nest == 0) *************** *** 903,909 **** scriptitem_T *si; sn_prl_T *pp; ! if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) return; si = SCRIPT_ITEM(current_sctx.sc_sid); if (si->sn_prof_on && SOURCING_LNUM >= 1) --- 903,909 ---- scriptitem_T *si; sn_prl_T *pp; ! if (!SCRIPT_ID_VALID(current_sctx.sc_sid)) return; si = SCRIPT_ITEM(current_sctx.sc_sid); if (si->sn_prof_on && SOURCING_LNUM >= 1) *************** *** 938,944 **** { scriptitem_T *si; ! if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) return; si = SCRIPT_ITEM(current_sctx.sc_sid); if (si->sn_prof_on && si->sn_prl_idx >= 0) --- 938,944 ---- { scriptitem_T *si; ! if (!SCRIPT_ID_VALID(current_sctx.sc_sid)) return; si = SCRIPT_ITEM(current_sctx.sc_sid); if (si->sn_prof_on && si->sn_prl_idx >= 0) *************** *** 954,960 **** scriptitem_T *si; sn_prl_T *pp; ! if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) return; si = SCRIPT_ITEM(current_sctx.sc_sid); if (si->sn_prof_on && si->sn_prl_idx >= 0 --- 954,960 ---- scriptitem_T *si; sn_prl_T *pp; ! if (!SCRIPT_ID_VALID(current_sctx.sc_sid)) return; si = SCRIPT_ITEM(current_sctx.sc_sid); if (si->sn_prof_on && si->sn_prl_idx >= 0 *** ../vim-8.2.1538/src/scriptfile.c 2020-08-20 15:02:38.532535000 +0200 --- src/scriptfile.c 2020-08-29 13:18:48.846682967 +0200 *************** *** 1517,1523 **** if (eap->addr_count > 0) { // :script {scriptId}: edit the script ! if (eap->line2 < 1 || eap->line2 > script_items.ga_len) emsg(_(e_invarg)); else { --- 1517,1523 ---- if (eap->addr_count > 0) { // :script {scriptId}: edit the script ! if (!SCRIPT_ID_VALID(eap->line2)) emsg(_(e_invarg)); else { *** ../vim-8.2.1538/src/vim9compile.c 2020-08-27 23:57:50.272069276 +0200 --- src/vim9compile.c 2020-08-29 13:24:18.889518167 +0200 *************** *** 1661,1667 **** int idx; // First look the name up in the hashtable. ! if (sid <= 0 || sid > script_items.ga_len) return -1; ht = &SCRIPT_VARS(sid); di = find_var_in_ht(ht, 0, name, TRUE); --- 1661,1667 ---- int idx; // First look the name up in the hashtable. ! if (!SCRIPT_ID_VALID(sid)) return -1; ht = &SCRIPT_VARS(sid); di = find_var_in_ht(ht, 0, name, TRUE); *************** *** 1692,1698 **** { int idx; ! if (current_sctx.sc_sid <= 0) return NULL; if (cctx != NULL) for (idx = 0; idx < cctx->ctx_imports.ga_len; ++idx) --- 1692,1698 ---- { int idx; ! if (!SCRIPT_ID_VALID(current_sctx.sc_sid)) return NULL; if (cctx != NULL) for (idx = 0; idx < cctx->ctx_imports.ga_len; ++idx) *************** *** 1712,1720 **** imported_T * find_imported_in_script(char_u *name, size_t len, int sid) { ! scriptitem_T *si = SCRIPT_ITEM(sid); int idx; for (idx = 0; idx < si->sn_imports.ga_len; ++idx) { imported_T *import = ((imported_T *)si->sn_imports.ga_data) + idx; --- 1712,1723 ---- imported_T * find_imported_in_script(char_u *name, size_t len, int sid) { ! scriptitem_T *si; int idx; + if (!SCRIPT_ID_VALID(sid)) + return NULL; + si = SCRIPT_ITEM(sid); for (idx = 0; idx < si->sn_imports.ga_len; ++idx) { imported_T *import = ((imported_T *)si->sn_imports.ga_data) + idx; *************** *** 1966,1975 **** char_u **end, // end of variable int error) // when TRUE may give error { ! scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid); ! int idx = get_script_item_idx(current_sctx.sc_sid, name, FALSE); imported_T *import; if (idx == -1 || si->sn_version != SCRIPT_VERSION_VIM9) { // variable is not in sn_var_vals: old style script. --- 1969,1982 ---- char_u **end, // end of variable int error) // when TRUE may give error { ! scriptitem_T *si; ! int idx; imported_T *import; + if (!SCRIPT_ID_VALID(current_sctx.sc_sid)) + return FAIL; + si = SCRIPT_ITEM(current_sctx.sc_sid); + idx = get_script_item_idx(current_sctx.sc_sid, name, FALSE); if (idx == -1 || si->sn_version != SCRIPT_VERSION_VIM9) { // variable is not in sn_var_vals: old style script. *************** *** 4750,4764 **** scriptvar_sid = current_sctx.sc_sid; if (import != NULL) scriptvar_sid = import->imp_sid; ! scriptvar_idx = get_script_item_idx(scriptvar_sid, ! rawname, TRUE); ! if (scriptvar_idx >= 0) { ! scriptitem_T *si = SCRIPT_ITEM(scriptvar_sid); ! svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + scriptvar_idx; ! type = sv->sv_type; } } else if (name[1] == ':' && name[2] != NUL) --- 4757,4774 ---- scriptvar_sid = current_sctx.sc_sid; if (import != NULL) scriptvar_sid = import->imp_sid; ! if (SCRIPT_ID_VALID(scriptvar_sid)) { ! scriptvar_idx = get_script_item_idx(scriptvar_sid, ! rawname, TRUE); ! if (scriptvar_idx > 0) ! { ! scriptitem_T *si = SCRIPT_ITEM(scriptvar_sid); ! svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + scriptvar_idx; ! type = sv->sv_type; ! } } } else if (name[1] == ':' && name[2] != NUL) *** ../vim-8.2.1538/src/testdir/test_vim9_script.vim 2020-08-27 22:42:59.416097708 +0200 --- src/testdir/test_vim9_script.vim 2020-08-29 13:37:07.254944378 +0200 *************** *** 4,9 **** --- 4,10 ---- source term_util.vim source view_util.vim source vim9.vim + source shared.vim def Test_syntax() let var = 234 *************** *** 3252,3257 **** --- 3253,3266 ---- delete('rtp', 'rf') enddef + def Test_invalid_sid() + assert_fails('func 1234_func', 'E123:') + if RunVim([], ['wq Xdidit'], '+"func 1_func"') + call assert_equal([], readfile('Xdidit')) + endif + delete('Xdidit') + enddef + " Keep this last, it messes up highlighting. def Test_substitute_cmd() new *** ../vim-8.2.1538/src/version.c 2020-08-29 12:57:12.587813107 +0200 --- src/version.c 2020-08-29 13:37:37.602849424 +0200 *************** *** 756,757 **** --- 756,759 ---- { /* Add new patch number below this line */ + /**/ + 1539, /**/ -- ### Hiroshima 45, Chernobyl 86, Windows 95 ### /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///