Patch 8.2.1867

6 views
Skip to first unread message

Bram Moolenaar

unread,
Oct 19, 2020, 2:46:15 PM10/19/20
to vim...@googlegroups.com

Patch 8.2.1867
Problem: Vim9: argument to add() not checked for blob.
Solution: Add the BLOBAPPEND instruction.
Files: src/vim9.h, src/vim9compile.c, src/vim9execute.c, src/errors.h,
src/testdir/test_vim9_func.vim,
src/testdir/test_vim9_disassemble.vim


*** ../vim-8.2.1866/src/vim9.h 2020-10-19 19:02:36.853261655 +0200
--- src/vim9.h 2020-10-19 20:23:16.084142073 +0200
***************
*** 126,131 ****
--- 126,132 ----
ISN_ANYINDEX, // [expr] runtime index
ISN_ANYSLICE, // [expr:expr] runtime slice
ISN_SLICE, // drop isn_arg.number items from start of list
+ ISN_BLOBAPPEND, // append to a blob, like add()
ISN_GETITEM, // push list item, isn_arg.number is the index
ISN_MEMBER, // dict[member]
ISN_STRINGMEMBER, // dict.member using isn_arg.string
*** ../vim-8.2.1866/src/vim9compile.c 2020-10-19 19:02:36.857261645 +0200
--- src/vim9compile.c 2020-10-19 20:39:10.545495598 +0200
***************
*** 1521,1526 ****
--- 1521,1548 ----
}

/*
+ * Generate an ISN_BLOBAPPEND instruction. Works like add().
+ * Argument count is already checked.
+ */
+ static int
+ generate_BLOBAPPEND(cctx_T *cctx)
+ {
+ garray_T *stack = &cctx->ctx_type_stack;
+ type_T *item_type;
+
+ // Caller already checked that blob_type is a blob.
+ item_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
+ if (need_type(item_type, &t_number, -1, cctx, FALSE, FALSE) == FAIL)
+ return FAIL;
+
+ if (generate_instr(cctx, ISN_BLOBAPPEND) == NULL)
+ return FAIL;
+
+ --stack->ga_len; // drop the argument
+ return OK;
+ }
+
+ /*
* Generate an ISN_DCALL or ISN_UCALL instruction.
* Return FAIL if the number of arguments is wrong.
*/
***************
*** 2570,2582 ****
type_T *type = ((type_T **)stack->ga_data)[
stack->ga_len - 2];

- // TODO: also check for VAR_BLOB
if (type->tt_type == VAR_LIST)
{
// inline "add(list, item)" so that the type can be checked
res = generate_LISTAPPEND(cctx);
idx = -1;
}
}

if (idx >= 0)
--- 2592,2609 ----
type_T *type = ((type_T **)stack->ga_data)[
stack->ga_len - 2];

if (type->tt_type == VAR_LIST)
{
// inline "add(list, item)" so that the type can be checked
res = generate_LISTAPPEND(cctx);
idx = -1;
}
+ else if (type->tt_type == VAR_BLOB)
+ {
+ // inline "add(blob, nr)" so that the type can be checked
+ res = generate_BLOBAPPEND(cctx);
+ idx = -1;
+ }
}

if (idx >= 0)
***************
*** 5421,5427 ****
generate_PUSHS(cctx, NULL);
break;
case VAR_BLOB:
! generate_PUSHBLOB(cctx, NULL);
break;
case VAR_FUNC:
generate_PUSHFUNC(cctx, NULL, &t_func_void);
--- 5448,5454 ----
generate_PUSHS(cctx, NULL);
break;
case VAR_BLOB:
! generate_PUSHBLOB(cctx, blob_alloc());
break;
case VAR_FUNC:
generate_PUSHFUNC(cctx, NULL, &t_func_void);
***************
*** 7675,7680 ****
--- 7702,7708 ----
case ISN_ANYINDEX:
case ISN_ANYSLICE:
case ISN_BCALL:
+ case ISN_BLOBAPPEND:
case ISN_CATCH:
case ISN_CHECKLEN:
case ISN_CHECKNR:
*** ../vim-8.2.1866/src/vim9execute.c 2020-10-19 19:02:36.857261645 +0200
--- src/vim9execute.c 2020-10-19 20:31:23.638775112 +0200
***************
*** 2312,2317 ****
--- 2312,2340 ----
}
break;

+ case ISN_BLOBAPPEND:
+ {
+ typval_T *tv1 = STACK_TV_BOT(-2);
+ typval_T *tv2 = STACK_TV_BOT(-1);
+ blob_T *b = tv1->vval.v_blob;
+ int error = FALSE;
+ varnumber_T n;
+
+ // add a number to a blob
+ if (b == NULL)
+ {
+ SOURCING_LNUM = iptr->isn_lnum;
+ emsg(_(e_cannot_add_to_null_blob));
+ goto on_error;
+ }
+ n = tv_get_number_chk(tv2, &error);
+ if (error)
+ goto on_error;
+ ga_append(&b->bv_ga, (int)n);
+ --ectx.ec_stack.ga_len;
+ }
+ break;
+
// Computation with two arguments of unknown type
case ISN_OPANY:
{
***************
*** 3432,3437 ****
--- 3455,3461 ----
case ISN_STRINDEX: smsg("%4d STRINDEX", current); break;
case ISN_STRSLICE: smsg("%4d STRSLICE", current); break;
case ISN_LISTAPPEND: smsg("%4d LISTAPPEND", current); break;
+ case ISN_BLOBAPPEND: smsg("%4d BLOBAPPEND", current); break;
case ISN_LISTINDEX: smsg("%4d LISTINDEX", current); break;
case ISN_LISTSLICE: smsg("%4d LISTSLICE", current); break;
case ISN_ANYINDEX: smsg("%4d ANYINDEX", current); break;
*** ../vim-8.2.1866/src/errors.h 2020-10-19 19:02:36.857261645 +0200
--- src/errors.h 2020-10-19 20:28:56.595184155 +0200
***************
*** 284,287 ****
--- 284,289 ----
INIT(= N_("E1129: Throw with empty string"));
EXTERN char e_cannot_add_to_null_list[]
INIT(= N_("E1130: Cannot add to null list"));
+ EXTERN char e_cannot_add_to_null_blob[]
+ INIT(= N_("E1131: Cannot add to null blob"));
#endif
*** ../vim-8.2.1866/src/testdir/test_vim9_func.vim 2020-10-19 20:20:59.892531346 +0200
--- src/testdir/test_vim9_func.vim 2020-10-19 20:34:41.466227816 +0200
***************
*** 1791,1799 ****
enddef

def Test_blob_add()
! var b: blob = 0z12
! add(b, 0x34)
! assert_equal(0z1234, b)
enddef

def SID(): number
--- 1791,1815 ----
enddef

def Test_blob_add()
! var b1: blob = 0z12
! add(b1, 0x34)
! assert_equal(0z1234, b1)
!
! var b2: blob # defaults to empty blob
! add(b2, 0x67)
! assert_equal(0z67, b2)
!
! var lines =<< trim END
! var b: blob
! add(b, "x")
! END
! CheckDefFailure(lines, 'E1012:', 2)
!
! lines =<< trim END
! var b: blob = test_null_blob()
! add(b, 123)
! END
! CheckDefExecFailure(lines, 'E1131:', 2)
enddef

def SID(): number
*** ../vim-8.2.1866/src/testdir/test_vim9_disassemble.vim 2020-10-19 19:02:36.857261645 +0200
--- src/testdir/test_vim9_disassemble.vim 2020-10-19 20:42:37.773018704 +0200
***************
*** 301,306 ****
--- 301,334 ----
res)
enddef

+ def s:BlobAdd()
+ var b: blob = 0z
+ add(b, 123)
+ add(b, g:aNumber)
+ enddef
+
+ def Test_disassemble_blob_add()
+ var res = execute('disass s:BlobAdd')
+ assert_match('<SNR>\d*_BlobAdd\_s*' ..
+ 'var b: blob = 0z\_s*' ..
+ '\d PUSHBLOB 0z\_s*' ..
+ '\d STORE $0\_s*' ..
+ 'add(b, 123)\_s*' ..
+ '\d LOAD $0\_s*' ..
+ '\d PUSHNR 123\_s*' ..
+ '\d BLOBAPPEND\_s*' ..
+ '\d DROP\_s*' ..
+ 'add(b, g:aNumber)\_s*' ..
+ '\d LOAD $0\_s*' ..
+ '\d\+ LOADG g:aNumber\_s*' ..
+ '\d\+ CHECKTYPE number stack\[-1\]\_s*' ..
+ '\d\+ BLOBAPPEND\_s*' ..
+ '\d\+ DROP\_s*' ..
+ '\d\+ PUSHNR 0\_s*' ..
+ '\d\+ RETURN',
+ res)
+ enddef
+
def s:ScriptFuncUnlet()
g:somevar = "value"
unlet g:somevar
*** ../vim-8.2.1866/src/version.c 2020-10-19 20:20:59.892531346 +0200
--- src/version.c 2020-10-19 20:24:02.828009395 +0200
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 1867,
/**/

--
A fool learns from his mistakes, a wise man from someone else's.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages