Mercurial > vim
diff src/eval.c @ 15456:f01eb1aed348 v8.1.0736
patch 8.1.0736: code for Blob not sufficiently tested
commit https://github.com/vim/vim/commit/c0f5a78c15b194f23bedb82e6825e34f481e6532
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jan 13 15:16:13 2019 +0100
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().
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 13 Jan 2019 15:30:08 +0100 |
parents | 1d2b5c016f17 |
children | 0f8065d7d68c |
line wrap: on
line diff
--- a/src/eval.c +++ b/src/eval.c @@ -1983,9 +1983,9 @@ get_lval( } if (rettv != NULL && !(rettv->v_type == VAR_LIST - || rettv->vval.v_list != NULL) + && rettv->vval.v_list != NULL) && !(rettv->v_type == VAR_BLOB - || rettv->vval.v_blob != NULL)) + && rettv->vval.v_blob != NULL)) { if (!quiet) EMSG(_("E709: [:] requires a List or Blob value")); @@ -2109,6 +2109,8 @@ get_lval( } else if (lp->ll_tv->v_type == VAR_BLOB) { + long bloblen = blob_len(lp->ll_tv->vval.v_blob); + /* * Get the number and item for the only or first index of the List. */ @@ -2120,16 +2122,26 @@ get_lval( clear_tv(&var1); if (lp->ll_n1 < 0 - || lp->ll_n1 > blob_len(lp->ll_tv->vval.v_blob)) + || 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); + clear_tv(&var2); return NULL; } if (lp->ll_range && !lp->ll_empty2) { lp->ll_n2 = (long)tv_get_number(&var2); clear_tv(&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; @@ -2241,6 +2253,7 @@ set_var_lval( if (lp->ll_blob != NULL) { int error = FALSE, val; + if (op != NULL && *op != '=') { EMSG2(_(e_letwrong), op); @@ -2249,17 +2262,23 @@ set_var_lval( if (lp->ll_range && rettv->v_type == VAR_BLOB) { - int i; - - if (blob_len(rettv->vval.v_blob) != blob_len(lp->ll_blob)) - { - EMSG(_("E972: Blob value has more items than target")); + int il, ir; + + if (lp->ll_empty2) + lp->ll_n2 = blob_len(lp->ll_blob) - 1; + + if (lp->ll_n2 - lp->ll_n1 + 1 != blob_len(rettv->vval.v_blob)) + { + EMSG(_("E972: Blob value does not have the right number of bytes")); return; } - - for (i = lp->ll_n1; i <= lp->ll_n2; i++) - blob_set(lp->ll_blob, i, - blob_get(rettv->vval.v_blob, i)); + if (lp->ll_empty2) + lp->ll_n2 = blob_len(lp->ll_blob); + + ir = 0; + for (il = lp->ll_n1; il <= lp->ll_n2; il++) + blob_set(lp->ll_blob, il, + blob_get(rettv->vval.v_blob, ir++)); } else { @@ -2278,8 +2297,7 @@ set_var_lval( if (lp->ll_n1 == gap->ga_len) ++gap->ga_len; } - else - EMSG(_(e_invrange)); + // error for invalid range was already given in get_lval() } } } @@ -2312,7 +2330,7 @@ set_var_lval( else if (lp->ll_range) { listitem_T *ll_li = lp->ll_li; - int ll_n1 = lp->ll_n1; + int ll_n1 = lp->ll_n1; /* * Check whether any of the list items is locked @@ -3354,6 +3372,8 @@ eval0( { int ret; char_u *p; + int did_emsg_before = did_emsg; + int called_emsg_before = called_emsg; p = skipwhite(arg); ret = eval1(&p, rettv, evaluate); @@ -3364,9 +3384,11 @@ eval0( /* * Report the invalid expression unless the expression evaluation has * been cancelled due to an aborting error, an interrupt, or an - * exception. + * exception, or we already gave a more specific error. + * Also check called_emsg for when using assert_fails(). */ - if (!aborting()) + if (!aborting() && did_emsg == did_emsg_before + && called_emsg == called_emsg_before) EMSG2(_(e_invexpr2), arg); ret = FAIL; } @@ -4195,7 +4217,7 @@ eval7( { if (!vim_isxdigit(bp[1])) { - EMSG(_("E973: Blob literal should have an even number of hex characters'")); + EMSG(_("E973: Blob literal should have an even number of hex characters")); vim_free(blob); ret = FAIL; break; @@ -4632,7 +4654,7 @@ eval_index( len = 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) { @@ -8336,6 +8358,7 @@ ex_echo(exarg_T *eap) int atstart = TRUE; char_u numbuf[NUMBUFLEN]; int did_emsg_before = did_emsg; + int called_emsg_before = called_emsg; if (eap->skip) ++emsg_skip; @@ -8353,7 +8376,8 @@ ex_echo(exarg_T *eap) * has been cancelled due to an aborting error, an interrupt, or an * exception. */ - if (!aborting() && did_emsg == did_emsg_before) + if (!aborting() && did_emsg == did_emsg_before + && called_emsg == called_emsg_before) EMSG2(_(e_invexpr2), p); need_clr_eos = FALSE; break;