Skip to content

Commit e3d4685

Browse files
committed
patch 8.2.1539: using invalid script ID causes a crash
Problem: Using invalid script ID causes a crash. Solution: Check the script ID to be valid. (closes #6804)
1 parent 423a85a commit e3d4685

7 files changed

Lines changed: 43 additions & 21 deletions

File tree

src/evalvars.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ list_vim_vars(int *first)
524524
static void
525525
list_script_vars(int *first)
526526
{
527-
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len)
527+
if (SCRIPT_ID_VALID(current_sctx.sc_sid))
528528
list_hashtable_vars(&SCRIPT_VARS(current_sctx.sc_sid),
529529
"s:", FALSE, first);
530530
}
@@ -2609,7 +2609,7 @@ get_script_local_ht(void)
26092609
{
26102610
scid_T sid = current_sctx.sc_sid;
26112611

2612-
if (sid > 0 && sid <= script_items.ga_len)
2612+
if (SCRIPT_ID_VALID(sid))
26132613
return &SCRIPT_VARS(sid);
26142614
return NULL;
26152615
}

src/globals.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,9 @@ EXTERN int do_profiling INIT(= PROF_NONE); // PROF_ values
297297
# endif
298298
EXTERN garray_T script_items INIT5(0, 0, sizeof(scriptitem_T *), 20, NULL);
299299
# define SCRIPT_ITEM(id) (((scriptitem_T **)script_items.ga_data)[(id) - 1])
300-
# define SCRIPT_SV(id) (SCRIPT_ITEM(id)->sn_vars)
301-
# define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab)
300+
# define SCRIPT_ID_VALID(id) ((id) > 0 && (id) <= script_items.ga_len)
301+
# define SCRIPT_SV(id) (SCRIPT_ITEM(id)->sn_vars)
302+
# define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab)
302303

303304
# define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j]
304305

src/profiler.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,7 @@ script_prof_save(
761761
{
762762
scriptitem_T *si;
763763

764-
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len)
764+
if (SCRIPT_ID_VALID(current_sctx.sc_sid))
765765
{
766766
si = SCRIPT_ITEM(current_sctx.sc_sid);
767767
if (si->sn_prof_on && si->sn_pr_nest++ == 0)
@@ -778,7 +778,7 @@ script_prof_restore(proftime_T *tm)
778778
{
779779
scriptitem_T *si;
780780

781-
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len)
781+
if (SCRIPT_ID_VALID(current_sctx.sc_sid))
782782
{
783783
si = SCRIPT_ITEM(current_sctx.sc_sid);
784784
if (si->sn_prof_on && --si->sn_pr_nest == 0)
@@ -903,7 +903,7 @@ script_line_start(void)
903903
scriptitem_T *si;
904904
sn_prl_T *pp;
905905

906-
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
906+
if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
907907
return;
908908
si = SCRIPT_ITEM(current_sctx.sc_sid);
909909
if (si->sn_prof_on && SOURCING_LNUM >= 1)
@@ -938,7 +938,7 @@ script_line_exec(void)
938938
{
939939
scriptitem_T *si;
940940

941-
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
941+
if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
942942
return;
943943
si = SCRIPT_ITEM(current_sctx.sc_sid);
944944
if (si->sn_prof_on && si->sn_prl_idx >= 0)
@@ -954,7 +954,7 @@ script_line_end(void)
954954
scriptitem_T *si;
955955
sn_prl_T *pp;
956956

957-
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
957+
if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
958958
return;
959959
si = SCRIPT_ITEM(current_sctx.sc_sid);
960960
if (si->sn_prof_on && si->sn_prl_idx >= 0

src/scriptfile.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1517,7 +1517,7 @@ ex_scriptnames(exarg_T *eap)
15171517
if (eap->addr_count > 0)
15181518
{
15191519
// :script {scriptId}: edit the script
1520-
if (eap->line2 < 1 || eap->line2 > script_items.ga_len)
1520+
if (!SCRIPT_ID_VALID(eap->line2))
15211521
emsg(_(e_invarg));
15221522
else
15231523
{

src/testdir/test_vim9_script.vim

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ source check.vim
44
source term_util.vim
55
source view_util.vim
66
source vim9.vim
7+
source shared.vim
78

89
def Test_syntax()
910
let var = 234
@@ -3252,6 +3253,14 @@ def Test_cmdline_win()
32523253
delete('rtp', 'rf')
32533254
enddef
32543255

3256+
def Test_invalid_sid()
3257+
assert_fails('func <SNR>1234_func', 'E123:')
3258+
if RunVim([], ['wq Xdidit'], '+"func <SNR>1_func"')
3259+
call assert_equal([], readfile('Xdidit'))
3260+
endif
3261+
delete('Xdidit')
3262+
enddef
3263+
32553264
" Keep this last, it messes up highlighting.
32563265
def Test_substitute_cmd()
32573266
new

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,8 @@ static char *(features[]) =
754754

755755
static int included_patches[] =
756756
{ /* Add new patch number below this line */
757+
/**/
758+
1539,
757759
/**/
758760
1538,
759761
/**/

src/vim9compile.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,7 +1661,7 @@ get_script_item_idx(int sid, char_u *name, int check_writable)
16611661
int idx;
16621662

16631663
// First look the name up in the hashtable.
1664-
if (sid <= 0 || sid > script_items.ga_len)
1664+
if (!SCRIPT_ID_VALID(sid))
16651665
return -1;
16661666
ht = &SCRIPT_VARS(sid);
16671667
di = find_var_in_ht(ht, 0, name, TRUE);
@@ -1692,7 +1692,7 @@ find_imported(char_u *name, size_t len, cctx_T *cctx)
16921692
{
16931693
int idx;
16941694

1695-
if (current_sctx.sc_sid <= 0)
1695+
if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
16961696
return NULL;
16971697
if (cctx != NULL)
16981698
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)
17121712
imported_T *
17131713
find_imported_in_script(char_u *name, size_t len, int sid)
17141714
{
1715-
scriptitem_T *si = SCRIPT_ITEM(sid);
1715+
scriptitem_T *si;
17161716
int idx;
17171717

1718+
if (!SCRIPT_ID_VALID(sid))
1719+
return NULL;
1720+
si = SCRIPT_ITEM(sid);
17181721
for (idx = 0; idx < si->sn_imports.ga_len; ++idx)
17191722
{
17201723
imported_T *import = ((imported_T *)si->sn_imports.ga_data) + idx;
@@ -1966,10 +1969,14 @@ compile_load_scriptvar(
19661969
char_u **end, // end of variable
19671970
int error) // when TRUE may give error
19681971
{
1969-
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
1970-
int idx = get_script_item_idx(current_sctx.sc_sid, name, FALSE);
1972+
scriptitem_T *si;
1973+
int idx;
19711974
imported_T *import;
19721975

1976+
if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
1977+
return FAIL;
1978+
si = SCRIPT_ITEM(current_sctx.sc_sid);
1979+
idx = get_script_item_idx(current_sctx.sc_sid, name, FALSE);
19731980
if (idx == -1 || si->sn_version != SCRIPT_VERSION_VIM9)
19741981
{
19751982
// 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)
47504757
scriptvar_sid = current_sctx.sc_sid;
47514758
if (import != NULL)
47524759
scriptvar_sid = import->imp_sid;
4753-
scriptvar_idx = get_script_item_idx(scriptvar_sid,
4754-
rawname, TRUE);
4755-
if (scriptvar_idx >= 0)
4760+
if (SCRIPT_ID_VALID(scriptvar_sid))
47564761
{
4757-
scriptitem_T *si = SCRIPT_ITEM(scriptvar_sid);
4758-
svar_T *sv =
4762+
scriptvar_idx = get_script_item_idx(scriptvar_sid,
4763+
rawname, TRUE);
4764+
if (scriptvar_idx > 0)
4765+
{
4766+
scriptitem_T *si = SCRIPT_ITEM(scriptvar_sid);
4767+
svar_T *sv =
47594768
((svar_T *)si->sn_var_vals.ga_data)
47604769
+ scriptvar_idx;
4761-
type = sv->sv_type;
4770+
type = sv->sv_type;
4771+
}
47624772
}
47634773
}
47644774
else if (name[1] == ':' && name[2] != NUL)

0 commit comments

Comments
 (0)