To: vim_dev@googlegroups.com Subject: Patch 8.2.3284 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3284 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) Files: 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 *** ../vim-8.2.3283/src/blob.c 2021-07-23 20:37:52.018322443 +0200 --- src/blob.c 2021-08-04 19:08:21.701051044 +0200 *************** *** 412,427 **** * "remove({blob})" function */ void ! blob_remove(typval_T *argvars, typval_T *rettv) { int error = FALSE; long idx; long end; 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; --- 412,430 ---- * "remove({blob})" function */ void ! 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) { int len = blob_len(b); char_u *p; *** ../vim-8.2.3283/src/errors.h 2021-08-04 16:09:19.973646545 +0200 --- src/errors.h 2021-08-04 19:08:21.701051044 +0200 *************** *** 366,372 **** 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_unknown_error_while_executing_str[] INIT(= N_("E1099: Unknown error while executing %s")); EXTERN char e_cannot_declare_script_variable_in_function[] --- 366,373 ---- INIT(= N_("E1096: Returning a value in a function without a return type")); EXTERN char e_line_incomplete[] INIT(= N_("E1097: Line incomplete")); ! 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[] *** ../vim-8.2.3283/src/eval.c 2021-08-01 12:01:45.936414564 +0200 --- src/eval.c 2021-08-04 19:08:21.701051044 +0200 *************** *** 1749,1755 **** } else { ! emsg(_(e_listreq)); clear_tv(&tv); } } --- 1749,1755 ---- } else { ! emsg(_(e_string_list_or_blob_required)); clear_tv(&tv); } } *** ../vim-8.2.3283/src/list.c 2021-07-27 22:00:39.745712396 +0200 --- src/list.c 2021-08-04 19:08:21.701051044 +0200 *************** *** 2817,2861 **** if (argvars[0].v_type == VAR_BLOB) { ! int val, len; ! char_u *p; ! if (argvars[0].vval.v_blob == 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) { ! 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; - 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; ! copy_tv(&argvars[0], rettv); } else if (argvars[0].v_type != VAR_LIST) semsg(_(e_listblobarg), "insert()"); --- 2817,2865 ---- if (argvars[0].v_type == VAR_BLOB) { ! blob_T *b = argvars[0].vval.v_blob; ! if (b == NULL) { if (in_vim9script()) emsg(_(e_cannot_add_to_null_blob)); } ! else if (!value_check_lock(b->bv_lock, ! (char_u *)N_("insert() argument"), TRUE)) { ! 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; ! if (val < 0 || val > 255) { ! semsg(_(e_invarg2), tv_get_string(&argvars[1])); return; } ! 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); ! } } else if (argvars[0].v_type != VAR_LIST) semsg(_(e_listblobarg), "insert()"); *************** *** 2917,2923 **** 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); else if (argvars[0].v_type == VAR_LIST) list_remove(argvars, rettv, arg_errmsg); else --- 2921,2927 ---- 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, arg_errmsg); else if (argvars[0].v_type == VAR_LIST) list_remove(argvars, rettv, arg_errmsg); else *** ../vim-8.2.3283/src/proto/blob.pro 2021-04-17 20:44:52.442520718 +0200 --- src/proto/blob.pro 2021-08-04 19:08:21.701051044 +0200 *************** *** 18,22 **** 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); /* vim: set ft=c : */ --- 18,22 ---- 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, char_u *arg_errmsg); /* vim: set ft=c : */ *** ../vim-8.2.3283/src/testdir/test_blob.vim 2021-07-27 22:00:39.753712380 +0200 --- src/testdir/test_blob.vim 2021-08-04 19:22:47.195217342 +0200 *************** *** 428,433 **** --- 428,450 ---- 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,548 **** --- 560,581 ---- 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() *** ../vim-8.2.3283/src/testdir/test_eval_stuff.vim 2021-06-17 22:08:13.376738576 +0200 --- src/testdir/test_eval_stuff.vim 2021-08-04 19:08:21.701051044 +0200 *************** *** 65,73 **** 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:') if 0 /1/5/2/s/\n --- 65,73 ---- endfunc 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:') if 0 /1/5/2/s/\n *** ../vim-8.2.3283/src/version.c 2021-08-04 17:03:56.051252245 +0200 --- src/version.c 2021-08-04 19:10:34.972786468 +0200 *************** *** 757,758 **** --- 757,760 ---- { /* Add new patch number below this line */ + /**/ + 3284, /**/ -- GUARD #1: What, ridden on a horse? ARTHUR: Yes! GUARD #1: You're using coconuts! ARTHUR: What? GUARD #1: You've got two empty halves of coconut and you're bangin' 'em together. The Quest for the Holy Grail (Monty Python) /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///