summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-08-29 13:39:17 +0200
committerBram Moolenaar <Bram@vim.org>2020-08-29 13:39:17 +0200
commite3d4685f1f716e0c516332101d85e0930f20fc59 (patch)
tree60b4b08d87d23ceb87227df3bedf8aa16305f21c /src
parent423a85a11a9d3d658906aea715fed7fe6aa83cd8 (diff)
patch 8.2.1539: using invalid script ID causes a crashv8.2.1539
Problem: Using invalid script ID causes a crash. Solution: Check the script ID to be valid. (closes #6804)
Diffstat (limited to 'src')
-rw-r--r--src/evalvars.c4
-rw-r--r--src/globals.h5
-rw-r--r--src/profiler.c10
-rw-r--r--src/scriptfile.c2
-rw-r--r--src/testdir/test_vim9_script.vim9
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c32
7 files changed, 43 insertions, 21 deletions
diff --git a/src/evalvars.c b/src/evalvars.c
index a946c75ba7..ecd0ce6bd5 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -524,7 +524,7 @@ list_vim_vars(int *first)
static void
list_script_vars(int *first)
{
- if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len)
+ if (SCRIPT_ID_VALID(current_sctx.sc_sid))
list_hashtable_vars(&SCRIPT_VARS(current_sctx.sc_sid),
"s:", FALSE, first);
}
@@ -2609,7 +2609,7 @@ get_script_local_ht(void)
{
scid_T sid = current_sctx.sc_sid;
- if (sid > 0 && sid <= script_items.ga_len)
+ if (SCRIPT_ID_VALID(sid))
return &SCRIPT_VARS(sid);
return NULL;
}
diff --git a/src/globals.h b/src/globals.h
index e883c56f63..1a764b5091 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -297,8 +297,9 @@ EXTERN int do_profiling INIT(= PROF_NONE); // PROF_ values
# 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 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]
diff --git a/src/profiler.c b/src/profiler.c
index 647934d522..7896897a44 100644
--- a/src/profiler.c
+++ b/src/profiler.c
@@ -761,7 +761,7 @@ script_prof_save(
{
scriptitem_T *si;
- if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len)
+ 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,7 +778,7 @@ script_prof_restore(proftime_T *tm)
{
scriptitem_T *si;
- if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len)
+ 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,7 +903,7 @@ script_line_start(void)
scriptitem_T *si;
sn_prl_T *pp;
- if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
+ 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,7 +938,7 @@ script_line_exec(void)
{
scriptitem_T *si;
- if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
+ 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,7 +954,7 @@ script_line_end(void)
scriptitem_T *si;
sn_prl_T *pp;
- if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
+ 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
diff --git a/src/scriptfile.c b/src/scriptfile.c
index 27d0eb2a52..e075236953 100644
--- a/src/scriptfile.c
+++ b/src/scriptfile.c
@@ -1517,7 +1517,7 @@ ex_scriptnames(exarg_T *eap)
if (eap->addr_count > 0)
{
// :script {scriptId}: edit the script
- if (eap->line2 < 1 || eap->line2 > script_items.ga_len)
+ if (!SCRIPT_ID_VALID(eap->line2))
emsg(_(e_invarg));
else
{
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 054fe4cbfc..49aacb0fab 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -4,6 +4,7 @@ source check.vim
source term_util.vim
source view_util.vim
source vim9.vim
+source shared.vim
def Test_syntax()
let var = 234
@@ -3252,6 +3253,14 @@ def Test_cmdline_win()
delete('rtp', 'rf')
enddef
+def Test_invalid_sid()
+ assert_fails('func <SNR>1234_func', 'E123:')
+ if RunVim([], ['wq Xdidit'], '+"func <SNR>1_func"')
+ call assert_equal([], readfile('Xdidit'))
+ endif
+ delete('Xdidit')
+enddef
+
" Keep this last, it messes up highlighting.
def Test_substitute_cmd()
new
diff --git a/src/version.c b/src/version.c
index 9e3430a106..ba308cdba9 100644
--- a/src/version.c
+++ b/src/version.c
@@ -755,6 +755,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1539,
+/**/
1538,
/**/
1537,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 5e4bfdb76c..bec6988e54 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1661,7 +1661,7 @@ get_script_item_idx(int sid, char_u *name, int check_writable)
int idx;
// First look the name up in the hashtable.
- if (sid <= 0 || sid > script_items.ga_len)
+ if (!SCRIPT_ID_VALID(sid))
return -1;
ht = &SCRIPT_VARS(sid);
di = find_var_in_ht(ht, 0, name, TRUE);
@@ -1692,7 +1692,7 @@ find_imported(char_u *name, size_t len, cctx_T *cctx)
{
int idx;
- if (current_sctx.sc_sid <= 0)
+ if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
return NULL;
if (cctx != NULL)
for (idx = 0; idx < cctx->ctx_imports.ga_len; ++idx)
@@ -1712,9 +1712,12 @@ find_imported(char_u *name, size_t len, cctx_T *cctx)
imported_T *
find_imported_in_script(char_u *name, size_t len, int sid)
{
- scriptitem_T *si = SCRIPT_ITEM(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,10 +1969,14 @@ compile_load_scriptvar(
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);
+ 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,15 +4757,18 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
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)
+ if (SCRIPT_ID_VALID(scriptvar_sid))
{
- scriptitem_T *si = SCRIPT_ITEM(scriptvar_sid);
- svar_T *sv =
+ 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;
+ type = sv->sv_type;
+ }
}
}
else if (name[1] == ':' && name[2] != NUL)