aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval.c
diff options
context:
space:
mode:
authorSean Dewar <seandewar@users.noreply.github.com>2020-11-24 21:46:43 +0000
committerSean Dewar <seandewar@users.noreply.github.com>2021-09-15 21:19:29 +0100
commitbfeecd0b418cf03a974c57082f4fc647b90aef06 (patch)
tree1e7ffd77738dfe99ebc5eca0f57d7da97d884cfe /src/nvim/eval.c
parent9095101743b2606fb1d5f7a5a1216f22d2fb2b4a (diff)
downloadrneovim-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.c38
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;