]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.0665: Locked variable can be changed in a :for loop v9.1.0665
authorzeertzjq <zeertzjq@outlook.com>
Thu, 8 Aug 2024 19:05:57 +0000 (21:05 +0200)
committerChristian Brabandt <cb@256bit.org>
Thu, 8 Aug 2024 19:05:57 +0000 (21:05 +0200)
Problem:  Locked variable can be changed in a :for loop.
Solution: Always do a full permission check on the first loop iteration
          where ASSIGN_DECL is not set (zeertzjq).

related: #12470
fixes: #15450
closes: #15454

Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/evalvars.c
src/testdir/test_eval_stuff.vim
src/version.c

index 6facbeb138fd5f4706e29d833ed5aa2ffa8b253e..f18b51637b080a5592808c6d573a984aa8f230bb 100644 (file)
@@ -4100,7 +4100,7 @@ set_var_const(
 
            // Modifying a final variable with a List value using the "+="
            // operator is allowed.  For other types, it is not allowed.
-           if (((flags & ASSIGN_FOR_LOOP) == 0
+           if ((((flags & ASSIGN_FOR_LOOP) == 0 || (flags & ASSIGN_DECL) == 0)
                        && ((flags & ASSIGN_COMPOUND_OP) == 0
                            || !type_inplace_modifiable))
                                 ? var_check_permission(di, name) == FAIL
index a346399eb513bbf2c45a4c98f5d823d206e7edbc..1b17108c4f3ff5daa3d940114576827aac225153 100644 (file)
@@ -2,6 +2,7 @@
 
 source view_util.vim
 source shared.vim
+import './vim9.vim' as v9
 
 function s:foo() abort
   try
@@ -126,7 +127,31 @@ func Test_for_invalid()
   call assert_fails("for x in 99", 'E1098:')
   call assert_fails("for x in function('winnr')", 'E1098:')
   call assert_fails("for x in {'a': 9}", 'E1098:')
-  call assert_fails("for v:maxcol in range(1)", 'E46:')
+
+  let lines =<< trim END
+    for v:maxcol in range(5)
+    endfor
+  END
+
+  let save_v_maxcol = v:maxcol
+  call v9.CheckLegacyAndVim9Failure(lines, 'E46:')
+  call assert_equal(save_v_maxcol, v:maxcol)
+
+  let lines =<< trim END
+    for g:constvar in range(5)
+    endfor
+  END
+
+  const g:constvar = 10
+  call v9.CheckLegacyAndVim9Failure(lines, 'E741:')
+  call assert_equal(10, g:constvar)
+  unlet g:constvar
+
+  let g:constvar = 10
+  lockvar 0 g:constvar
+  call v9.CheckLegacyAndVim9Failure(lines, 'E1122:')
+  call assert_equal(10, g:constvar)
+  unlet g:constvar
 
   if 0
     /1/5/2/s/\n
index ce5894f89aff5960673af85fe913202d1bce6297..1b7e423353c4e7a2c235d167b7baeeb13eba2072 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    665,
 /**/
     664,
 /**/