diff options
author | Sean Dewar <seandewar@users.noreply.github.com> | 2020-11-24 21:46:43 +0000 |
---|---|---|
committer | Sean Dewar <seandewar@users.noreply.github.com> | 2021-09-15 21:19:29 +0100 |
commit | bfeecd0b418cf03a974c57082f4fc647b90aef06 (patch) | |
tree | 1e7ffd77738dfe99ebc5eca0f57d7da97d884cfe /src/nvim/eval.c | |
parent | 9095101743b2606fb1d5f7a5a1216f22d2fb2b4a (diff) | |
download | rneovim-bfeecd0b418cf03a974c57082f4fc647b90aef06.tar.gz rneovim-bfeecd0b418cf03a974c57082f4fc647b90aef06.tar.bz2 rneovim-bfeecd0b418cf03a974c57082f4fc647b90aef06.zip |
vim-patch:8.1.0736: code for Blob not sufficiently tested
Problem: Code for Blob not sufficiently tested.
Solution: Add more tests. Fix uncovered crash. Add test_null_blob().
https://github.com/vim/vim/commit/c0f5a78c15b194f23bedb82e6825e34f481e6532
eval0 and ex_echo's emsg-specific changes have already been ported.
These tests uncover another crash that was fixed in v8.1.0738.
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r-- | src/nvim/eval.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index c3a9c0b9ca..29df1a168f 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -242,6 +242,7 @@ static struct vimvar { VV(VV__NULL_STRING, "_null_string", VAR_STRING, VV_RO), VV(VV__NULL_LIST, "_null_list", VAR_LIST, VV_RO), VV(VV__NULL_DICT, "_null_dict", VAR_DICT, VV_RO), + VV(VV__NULL_BLOB, "_null_blob", VAR_BLOB, VV_RO), VV(VV_LUA, "lua", VAR_PARTIAL, VV_RO), }; #undef VV @@ -2125,8 +2126,8 @@ char_u *get_lval(char_u *const name, typval_T *const rettv, return NULL; } if (rettv != NULL - && !(rettv->v_type == VAR_LIST || rettv->vval.v_list != NULL) - && !(rettv->v_type == VAR_BLOB || rettv->vval.v_blob != NULL)) { + && !(rettv->v_type == VAR_LIST && rettv->vval.v_list != NULL) + && !(rettv->v_type == VAR_BLOB && rettv->vval.v_blob != NULL)) { if (!quiet) { EMSG(_("E709: [:] requires a List or Blob value")); } @@ -2252,15 +2253,24 @@ char_u *get_lval(char_u *const name, typval_T *const rettv, } tv_clear(&var1); - if (lp->ll_n1 < 0 || lp->ll_n1 > tv_blob_len(lp->ll_tv->vval.v_blob)) { + const int bloblen = tv_blob_len(lp->ll_tv->vval.v_blob); + if (lp->ll_n1 < 0 || lp->ll_n1 > bloblen + || (lp->ll_range && lp->ll_n1 == bloblen)) { if (!quiet) { - EMSGN(_(e_listidx), lp->ll_n1); + EMSGN(_(e_blobidx), lp->ll_n1); } + tv_clear(&var2); return NULL; } if (lp->ll_range && !lp->ll_empty2) { lp->ll_n2 = (long)tv_get_number(&var2); tv_clear(&var2); + if (lp->ll_n2 < 0 || lp->ll_n2 >= bloblen || lp->ll_n2 < lp->ll_n1) { + if (!quiet) { + EMSGN(_(e_blobidx), lp->ll_n2); + } + return NULL; + } } lp->ll_blob = lp->ll_tv->vval.v_blob; lp->ll_tv = NULL; @@ -2364,13 +2374,20 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, } if (lp->ll_range && rettv->v_type == VAR_BLOB) { - if (tv_blob_len(rettv->vval.v_blob) != tv_blob_len(lp->ll_blob)) { - EMSG(_("E972: Blob value has more items than target")); + if (lp->ll_empty2) { + lp->ll_n2 = tv_blob_len(lp->ll_blob) - 1; + } + + if (lp->ll_n2 - lp->ll_n1 + 1 != tv_blob_len(rettv->vval.v_blob)) { + EMSG(_("E972: Blob value does not have the right number of bytes")); return; } + if (lp->ll_empty2) { + lp->ll_n2 = tv_blob_len(lp->ll_blob); + } - for (int i = lp->ll_n1; i <= lp->ll_n2; i++) { - tv_blob_set(lp->ll_blob, i, tv_blob_get(rettv->vval.v_blob, i)); + for (int il = lp->ll_n1, ir = 0; il <= lp->ll_n2; il++) { + tv_blob_set(lp->ll_blob, il, tv_blob_get(rettv->vval.v_blob, ir++)); } } else { bool error = false; @@ -2386,9 +2403,8 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, if (lp->ll_n1 == gap->ga_len) { gap->ga_len++; } - } else { - EMSG(_(e_invrange)); } + // error for invalid range was already given in get_lval() } } } else if (op != NULL && *op != '=') { @@ -4591,7 +4607,7 @@ eval_index( case VAR_BLOB: { len = tv_blob_len(rettv->vval.v_blob); if (range) { - // The resulting variable is a substring. If the indexes + // The resulting variable is a sub-blob. If the indexes // are out of range the result is empty. if (n1 < 0) { n1 = len + n1; |