]> granicus.if.org Git - vim/commitdiff
patch 8.2.3284: no error for insert() or remove() changing a locked blob v8.2.3284
authorSean Dewar <seandewar@users.noreply.github.com>
Wed, 4 Aug 2021 17:25:54 +0000 (19:25 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 4 Aug 2021 17:25:54 +0000 (19:25 +0200)
Problem:    No error for insert() or remove() changing a locked blob.
Solution:   Check a blob is not locked before changing it. (Sean Dewar,
            closes #8696)

src/blob.c
src/errors.h
src/eval.c
src/list.c
src/proto/blob.pro
src/testdir/test_blob.vim
src/testdir/test_eval_stuff.vim
src/version.c

index 57fe58b0558c02a1cfae2e66d43720521aa9d797..2138ac07403f0339b5f133f5510db6473e1048f6 100644 (file)
@@ -412,16 +412,19 @@ blob_set_range(blob_T *dest, long n1, long n2, typval_T *src)
  * "remove({blob})" function
  */
     void
-blob_remove(typval_T *argvars, typval_T *rettv)
+blob_remove(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg)
 {
+    blob_T     *b = argvars[0].vval.v_blob;
     int                error = FALSE;
     long       idx;
     long       end;
 
+    if (b != NULL && value_check_lock(b->bv_lock, arg_errmsg, TRUE))
+       return;
+
     idx = (long)tv_get_number_chk(&argvars[1], &error);
     if (!error)
     {
-       blob_T  *b = argvars[0].vval.v_blob;
        int     len = blob_len(b);
        char_u  *p;
 
index 44b2828f6a278651fbcf7b2809e0b5dabd6332b8..942cf658b49314a55a05e829980c253b5c339fae 100644 (file)
@@ -366,7 +366,8 @@ EXTERN char e_returning_value_in_function_without_return_type[]
        INIT(= N_("E1096: Returning a value in a function without a return type"));
 EXTERN char e_line_incomplete[]
        INIT(= N_("E1097: Line incomplete"));
-// E1098 unused
+EXTERN char e_string_list_or_blob_required[]
+       INIT(= N_("E1098: String, List or Blob required"));
 EXTERN char e_unknown_error_while_executing_str[]
        INIT(= N_("E1099: Unknown error while executing %s"));
 EXTERN char e_cannot_declare_script_variable_in_function[]
index 3688176ab616848660d80ae2dd5ceed31c643c31..550fe8e2ba91f2bb36c3017537c0a386d11ee8eb 100644 (file)
@@ -1749,7 +1749,7 @@ eval_for_line(
            }
            else
            {
-               emsg(_(e_listreq));
+               emsg(_(e_string_list_or_blob_required));
                clear_tv(&tv);
            }
        }
index c65c8df6f0b08d344b4b37e87593bf3364462d4f..bf24cee222c4dd8388443e301ddd33aa693839a2 100644 (file)
@@ -2817,45 +2817,49 @@ f_insert(typval_T *argvars, typval_T *rettv)
 
     if (argvars[0].v_type == VAR_BLOB)
     {
-       int         val, len;
-       char_u      *p;
+       blob_T  *b = argvars[0].vval.v_blob;
 
-       if (argvars[0].vval.v_blob == NULL)
+       if (b == NULL)
        {
            if (in_vim9script())
                emsg(_(e_cannot_add_to_null_blob));
-           return;
        }
-
-       len = blob_len(argvars[0].vval.v_blob);
-       if (argvars[2].v_type != VAR_UNKNOWN)
+       else if (!value_check_lock(b->bv_lock,
+                                    (char_u *)N_("insert() argument"), TRUE))
        {
-           before = (long)tv_get_number_chk(&argvars[2], &error);
+           int         val, len;
+           char_u      *p;
+
+           len = blob_len(b);
+           if (argvars[2].v_type != VAR_UNKNOWN)
+           {
+               before = (long)tv_get_number_chk(&argvars[2], &error);
+               if (error)
+                   return;             // type error; errmsg already given
+               if (before < 0 || before > len)
+               {
+                   semsg(_(e_invarg2), tv_get_string(&argvars[2]));
+                   return;
+               }
+           }
+           val = tv_get_number_chk(&argvars[1], &error);
            if (error)
-               return;         // type error; errmsg already given
-           if (before < 0 || before > len)
+               return;
+           if (val < 0 || val > 255)
            {
-               semsg(_(e_invarg2), tv_get_string(&argvars[2]));
+               semsg(_(e_invarg2), tv_get_string(&argvars[1]));
                return;
            }
-       }
-       val = tv_get_number_chk(&argvars[1], &error);
-       if (error)
-           return;
-       if (val < 0 || val > 255)
-       {
-           semsg(_(e_invarg2), tv_get_string(&argvars[1]));
-           return;
-       }
 
-       if (ga_grow(&argvars[0].vval.v_blob->bv_ga, 1) == FAIL)
-           return;
-       p = (char_u *)argvars[0].vval.v_blob->bv_ga.ga_data;
-       mch_memmove(p + before + 1, p + before, (size_t)len - before);
-       *(p + before) = val;
-       ++argvars[0].vval.v_blob->bv_ga.ga_len;
+           if (ga_grow(&b->bv_ga, 1) == FAIL)
+               return;
+           p = (char_u *)b->bv_ga.ga_data;
+           mch_memmove(p + before + 1, p + before, (size_t)len - before);
+           *(p + before) = val;
+           ++b->bv_ga.ga_len;
 
-       copy_tv(&argvars[0], rettv);
+           copy_tv(&argvars[0], rettv);
+       }
     }
     else if (argvars[0].v_type != VAR_LIST)
        semsg(_(e_listblobarg), "insert()");
@@ -2917,7 +2921,7 @@ f_remove(typval_T *argvars, typval_T *rettv)
     if (argvars[0].v_type == VAR_DICT)
        dict_remove(argvars, rettv, arg_errmsg);
     else if (argvars[0].v_type == VAR_BLOB)
-       blob_remove(argvars, rettv);
+       blob_remove(argvars, rettv, arg_errmsg);
     else if (argvars[0].v_type == VAR_LIST)
        list_remove(argvars, rettv, arg_errmsg);
     else
index 157f15bbcdf3b95c71dcd02dc7a505652788da48..5d80463e3d39c9fc73bb4de54c8036747106eaf1 100644 (file)
@@ -18,5 +18,5 @@ int blob_slice_or_index(blob_T *blob, int is_range, varnumber_T n1, varnumber_T
 int check_blob_index(long bloblen, varnumber_T n1, int quiet);
 int check_blob_range(long bloblen, varnumber_T n1, varnumber_T n2, int quiet);
 int blob_set_range(blob_T *dest, long n1, long n2, typval_T *src);
-void blob_remove(typval_T *argvars, typval_T *rettv);
+void blob_remove(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg);
 /* vim: set ft=c : */
index b41ca78f3a3609e742853ced06e25f8c0f6ff38e..d56c4f748a7a7f1508e1a9dfddcef0825aa5e3e4 100644 (file)
@@ -428,6 +428,23 @@ func Test_blob_func_remove()
       call remove(test_null_blob(), 1, 2)
   END
   call CheckLegacyAndVim9Failure(lines, 'E979:')
+
+  let lines =<< trim END
+      let b = 0zDEADBEEF
+      lockvar b
+      call remove(b, 0)
+      unlockvar b
+  END
+  call CheckScriptFailure(lines, 'E741:')
+
+  " can only check at script level, not in a :def function
+  let lines =<< trim END
+      vim9script
+      var b = 0zDEADBEEF
+      lockvar b
+      remove(b, 0)
+  END
+  call CheckScriptFailure(lines, 'E741:')
 endfunc
 
 func Test_blob_read_write()
@@ -543,6 +560,22 @@ func Test_blob_insert()
       insert(test_null_blob(), 0x33)
   END
   call CheckDefExecAndScriptFailure(lines, 'E1131:')
+
+  let lines =<< trim END
+      let b = 0zDEADBEEF
+      lockvar b
+      call insert(b, 3)
+      unlockvar b
+  END
+  call CheckScriptFailure(lines, 'E741:')
+
+  let lines =<< trim END
+      vim9script
+      var b = 0zDEADBEEF
+      lockvar b
+      insert(b, 3)
+  END
+  call CheckScriptFailure(lines, 'E741:')
 endfunc
 
 func Test_blob_reverse()
index 1fbb74bc4eb6c4273b73d2a0e07680d9c4ed38cb..ac9589d24caa5dee3c44a373134e14ce266c9193 100644 (file)
@@ -65,9 +65,9 @@ func Test_E963()
 endfunc
 
 func Test_for_invalid()
-  call assert_fails("for x in 99", 'E714:')
-  call assert_fails("for x in function('winnr')", 'E714:')
-  call assert_fails("for x in {'a': 9}", 'E714:')
+  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:')
 
   if 0
     /1/5/2/s/\n
index 35bb3910a33a1543f45e813014f15c68fa9880cc..1b1f7a60565c6148e557d553a2e5e47e023be616 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3284,
 /**/
     3283,
 /**/