summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-12-17 20:36:15 +0000
committerBram Moolenaar <Bram@vim.org>2021-12-17 20:36:15 +0000
commit422085f1c87cb6bea879158b8b05c4a5cf7ab48b (patch)
tree77f79d7635f99d99a4e70e29354455090802364d
parent71b768509250b12696e8cc90e5902029f1b5433d (diff)
downloadvim-git-422085f1c87cb6bea879158b8b05c4a5cf7ab48b.tar.gz
patch 8.2.3842: Vim9: can change locked list and list itemsv8.2.3842
Problem: Vim9: can change locked list and list items. Solution: Check that a list and list item isn't locked.
-rw-r--r--src/testdir/test_listdict.vim12
-rw-r--r--src/version.c2
-rw-r--r--src/vim9execute.c26
3 files changed, 31 insertions, 9 deletions
diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim
index 957520bcc..30f47adc6 100644
--- a/src/testdir/test_listdict.vim
+++ b/src/testdir/test_listdict.vim
@@ -719,6 +719,7 @@ func Test_list_locked_var_unlet()
call assert_equal(expected[depth][u][1], ps)
endfor
endfor
+
" Deleting a list range should fail if the range is locked
let l = [1, 2, 3, 4]
lockvar l[1:2]
@@ -848,6 +849,17 @@ func Test_let_lock_list()
call assert_fails('let l[1:2] = [0, 1]', 'E741:')
call assert_equal([1, 2, 3, 4], l)
unlet l
+
+ let lines =<< trim END
+ def TryUnletListItem(l: list<any>)
+ unlet l[0]
+ enddef
+ let l = [1, 2, 3, 4]
+ lockvar! l
+ call TryUnletListItem(l)
+ END
+ call CheckScriptFailure(lines, 'E741:')
+ unlet g:l
endfunc
" Locking part of the list
diff --git a/src/version.c b/src/version.c
index 5fffd7382..d90560f9b 100644
--- a/src/version.c
+++ b/src/version.c
@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3842,
+/**/
3841,
/**/
3840,
diff --git a/src/vim9execute.c b/src/vim9execute.c
index a376d00a5..afd0a613d 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -2898,18 +2898,26 @@ exec_instructions(ectx_T *ectx)
{
list_T *l = tv_dest->vval.v_list;
long n = (long)tv_idx->vval.v_number;
- listitem_T *li = NULL;
- li = list_find(l, n);
- if (li == NULL)
- {
- SOURCING_LNUM = iptr->isn_lnum;
- semsg(_(e_listidx), n);
+ if (l != NULL && value_check_lock(
+ l->lv_lock, NULL, FALSE))
status = FAIL;
- }
else
- // TODO: check for list or item locked
- listitem_remove(l, li);
+ {
+ listitem_T *li = list_find(l, n);
+
+ if (li == NULL)
+ {
+ SOURCING_LNUM = iptr->isn_lnum;
+ semsg(_(e_listidx), n);
+ status = FAIL;
+ }
+ else if (value_check_lock(li->li_tv.v_lock,
+ NULL, FALSE))
+ status = FAIL;
+ else
+ listitem_remove(l, li);
+ }
}
}
else