]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.3842: Vim9: can change locked list and list items v8.2.3842
authorBram Moolenaar <Bram@vim.org>
Fri, 17 Dec 2021 20:36:15 +0000 (20:36 +0000)
committerBram Moolenaar <Bram@vim.org>
Fri, 17 Dec 2021 20:36:15 +0000 (20:36 +0000)
Problem:    Vim9: can change locked list and list items.
Solution:   Check that a list and list item isn't locked.

src/testdir/test_listdict.vim
src/version.c
src/vim9execute.c

index 957520bcc80a2f3dbdff7eb9a3a1594edc84c954..30f47adc6b4cb8e31a668ba98a5ea73d30140eab 100644 (file)
@@ -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
index 5fffd7382b8ed9be4fde130a344fcda9c67c883f..d90560f9b1b518599de6226f4064465a280e5dcb 100644 (file)
@@ -749,6 +749,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3842,
 /**/
     3841,
 /**/
index a376d00a5142f322cbb61e1067e7c68ba03fc17c..afd0a613ddcba8f5e45f6b772de8eb16e89c7c03 100644 (file)
@@ -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