# HG changeset patch # User Bram Moolenaar # Date 1639773903 -3600 # Node ID 4d18b3a5254a55de23d203c13d087a227a9930d8 # Parent 05e524ae9236760ec84915ead9d02d14e74bfb57 patch 8.2.3842: Vim9: can change locked list and list items Commit: https://github.com/vim/vim/commit/422085f1c87cb6bea879158b8b05c4a5cf7ab48b Author: Bram Moolenaar Date: Fri Dec 17 20:36:15 2021 +0000 patch 8.2.3842: Vim9: can change locked list and list items Problem: Vim9: can change locked list and list items. Solution: Check that a list and list item isn't locked. diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim --- 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) + 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 --- 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 --- 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) + + if (l != NULL && value_check_lock( + l->lv_lock, NULL, FALSE)) + status = FAIL; + else { - SOURCING_LNUM = iptr->isn_lnum; - semsg(_(e_listidx), n); - status = FAIL; + 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 - // TODO: check for list or item locked - listitem_remove(l, li); } } else