comparison 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
comparison
equal deleted inserted replaced
15455:4e2baf1fe3eb 15456:f01eb1aed348
1981 clear_tv(&var1); 1981 clear_tv(&var1);
1982 return NULL; 1982 return NULL;
1983 } 1983 }
1984 if (rettv != NULL 1984 if (rettv != NULL
1985 && !(rettv->v_type == VAR_LIST 1985 && !(rettv->v_type == VAR_LIST
1986 || rettv->vval.v_list != NULL) 1986 && rettv->vval.v_list != NULL)
1987 && !(rettv->v_type == VAR_BLOB 1987 && !(rettv->v_type == VAR_BLOB
1988 || rettv->vval.v_blob != NULL)) 1988 && rettv->vval.v_blob != NULL))
1989 { 1989 {
1990 if (!quiet) 1990 if (!quiet)
1991 EMSG(_("E709: [:] requires a List or Blob value")); 1991 EMSG(_("E709: [:] requires a List or Blob value"));
1992 clear_tv(&var1); 1992 clear_tv(&var1);
1993 return NULL; 1993 return NULL;
2107 clear_tv(&var1); 2107 clear_tv(&var1);
2108 lp->ll_tv = &lp->ll_di->di_tv; 2108 lp->ll_tv = &lp->ll_di->di_tv;
2109 } 2109 }
2110 else if (lp->ll_tv->v_type == VAR_BLOB) 2110 else if (lp->ll_tv->v_type == VAR_BLOB)
2111 { 2111 {
2112 long bloblen = blob_len(lp->ll_tv->vval.v_blob);
2113
2112 /* 2114 /*
2113 * Get the number and item for the only or first index of the List. 2115 * Get the number and item for the only or first index of the List.
2114 */ 2116 */
2115 if (empty1) 2117 if (empty1)
2116 lp->ll_n1 = 0; 2118 lp->ll_n1 = 0;
2118 // is number or string 2120 // is number or string
2119 lp->ll_n1 = (long)tv_get_number(&var1); 2121 lp->ll_n1 = (long)tv_get_number(&var1);
2120 clear_tv(&var1); 2122 clear_tv(&var1);
2121 2123
2122 if (lp->ll_n1 < 0 2124 if (lp->ll_n1 < 0
2123 || lp->ll_n1 > blob_len(lp->ll_tv->vval.v_blob)) 2125 || lp->ll_n1 > bloblen
2126 || (lp->ll_range && lp->ll_n1 == bloblen))
2124 { 2127 {
2125 if (!quiet) 2128 if (!quiet)
2126 EMSGN(_(e_listidx), lp->ll_n1); 2129 EMSGN(_(e_blobidx), lp->ll_n1);
2130 clear_tv(&var2);
2127 return NULL; 2131 return NULL;
2128 } 2132 }
2129 if (lp->ll_range && !lp->ll_empty2) 2133 if (lp->ll_range && !lp->ll_empty2)
2130 { 2134 {
2131 lp->ll_n2 = (long)tv_get_number(&var2); 2135 lp->ll_n2 = (long)tv_get_number(&var2);
2132 clear_tv(&var2); 2136 clear_tv(&var2);
2137 if (lp->ll_n2 < 0
2138 || lp->ll_n2 >= bloblen
2139 || lp->ll_n2 < lp->ll_n1)
2140 {
2141 if (!quiet)
2142 EMSGN(_(e_blobidx), lp->ll_n2);
2143 return NULL;
2144 }
2133 } 2145 }
2134 lp->ll_blob = lp->ll_tv->vval.v_blob; 2146 lp->ll_blob = lp->ll_tv->vval.v_blob;
2135 lp->ll_tv = NULL; 2147 lp->ll_tv = NULL;
2136 } 2148 }
2137 else 2149 else
2239 cc = *endp; 2251 cc = *endp;
2240 *endp = NUL; 2252 *endp = NUL;
2241 if (lp->ll_blob != NULL) 2253 if (lp->ll_blob != NULL)
2242 { 2254 {
2243 int error = FALSE, val; 2255 int error = FALSE, val;
2256
2244 if (op != NULL && *op != '=') 2257 if (op != NULL && *op != '=')
2245 { 2258 {
2246 EMSG2(_(e_letwrong), op); 2259 EMSG2(_(e_letwrong), op);
2247 return; 2260 return;
2248 } 2261 }
2249 2262
2250 if (lp->ll_range && rettv->v_type == VAR_BLOB) 2263 if (lp->ll_range && rettv->v_type == VAR_BLOB)
2251 { 2264 {
2252 int i; 2265 int il, ir;
2253 2266
2254 if (blob_len(rettv->vval.v_blob) != blob_len(lp->ll_blob)) 2267 if (lp->ll_empty2)
2268 lp->ll_n2 = blob_len(lp->ll_blob) - 1;
2269
2270 if (lp->ll_n2 - lp->ll_n1 + 1 != blob_len(rettv->vval.v_blob))
2255 { 2271 {
2256 EMSG(_("E972: Blob value has more items than target")); 2272 EMSG(_("E972: Blob value does not have the right number of bytes"));
2257 return; 2273 return;
2258 } 2274 }
2259 2275 if (lp->ll_empty2)
2260 for (i = lp->ll_n1; i <= lp->ll_n2; i++) 2276 lp->ll_n2 = blob_len(lp->ll_blob);
2261 blob_set(lp->ll_blob, i, 2277
2262 blob_get(rettv->vval.v_blob, i)); 2278 ir = 0;
2279 for (il = lp->ll_n1; il <= lp->ll_n2; il++)
2280 blob_set(lp->ll_blob, il,
2281 blob_get(rettv->vval.v_blob, ir++));
2263 } 2282 }
2264 else 2283 else
2265 { 2284 {
2266 val = (int)tv_get_number_chk(rettv, &error); 2285 val = (int)tv_get_number_chk(rettv, &error);
2267 if (!error) 2286 if (!error)
2276 { 2295 {
2277 blob_set(lp->ll_blob, lp->ll_n1, val); 2296 blob_set(lp->ll_blob, lp->ll_n1, val);
2278 if (lp->ll_n1 == gap->ga_len) 2297 if (lp->ll_n1 == gap->ga_len)
2279 ++gap->ga_len; 2298 ++gap->ga_len;
2280 } 2299 }
2281 else 2300 // error for invalid range was already given in get_lval()
2282 EMSG(_(e_invrange));
2283 } 2301 }
2284 } 2302 }
2285 } 2303 }
2286 else if (op != NULL && *op != '=') 2304 else if (op != NULL && *op != '=')
2287 { 2305 {
2310 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name, FALSE)) 2328 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name, FALSE))
2311 ; 2329 ;
2312 else if (lp->ll_range) 2330 else if (lp->ll_range)
2313 { 2331 {
2314 listitem_T *ll_li = lp->ll_li; 2332 listitem_T *ll_li = lp->ll_li;
2315 int ll_n1 = lp->ll_n1; 2333 int ll_n1 = lp->ll_n1;
2316 2334
2317 /* 2335 /*
2318 * Check whether any of the list items is locked 2336 * Check whether any of the list items is locked
2319 */ 2337 */
2320 for (ri = rettv->vval.v_list->lv_first; ri != NULL && ll_li != NULL; ) 2338 for (ri = rettv->vval.v_list->lv_first; ri != NULL && ll_li != NULL; )
3352 char_u **nextcmd, 3370 char_u **nextcmd,
3353 int evaluate) 3371 int evaluate)
3354 { 3372 {
3355 int ret; 3373 int ret;
3356 char_u *p; 3374 char_u *p;
3375 int did_emsg_before = did_emsg;
3376 int called_emsg_before = called_emsg;
3357 3377
3358 p = skipwhite(arg); 3378 p = skipwhite(arg);
3359 ret = eval1(&p, rettv, evaluate); 3379 ret = eval1(&p, rettv, evaluate);
3360 if (ret == FAIL || !ends_excmd(*p)) 3380 if (ret == FAIL || !ends_excmd(*p))
3361 { 3381 {
3362 if (ret != FAIL) 3382 if (ret != FAIL)
3363 clear_tv(rettv); 3383 clear_tv(rettv);
3364 /* 3384 /*
3365 * Report the invalid expression unless the expression evaluation has 3385 * Report the invalid expression unless the expression evaluation has
3366 * been cancelled due to an aborting error, an interrupt, or an 3386 * been cancelled due to an aborting error, an interrupt, or an
3367 * exception. 3387 * exception, or we already gave a more specific error.
3388 * Also check called_emsg for when using assert_fails().
3368 */ 3389 */
3369 if (!aborting()) 3390 if (!aborting() && did_emsg == did_emsg_before
3391 && called_emsg == called_emsg_before)
3370 EMSG2(_(e_invexpr2), arg); 3392 EMSG2(_(e_invexpr2), arg);
3371 ret = FAIL; 3393 ret = FAIL;
3372 } 3394 }
3373 if (nextcmd != NULL) 3395 if (nextcmd != NULL)
3374 *nextcmd = check_nextcmd(p); 3396 *nextcmd = check_nextcmd(p);
4193 blob = blob_alloc(); 4215 blob = blob_alloc();
4194 for (bp = *arg + 2; vim_isxdigit(bp[0]); bp += 2) 4216 for (bp = *arg + 2; vim_isxdigit(bp[0]); bp += 2)
4195 { 4217 {
4196 if (!vim_isxdigit(bp[1])) 4218 if (!vim_isxdigit(bp[1]))
4197 { 4219 {
4198 EMSG(_("E973: Blob literal should have an even number of hex characters'")); 4220 EMSG(_("E973: Blob literal should have an even number of hex characters"));
4199 vim_free(blob); 4221 vim_free(blob);
4200 ret = FAIL; 4222 ret = FAIL;
4201 break; 4223 break;
4202 } 4224 }
4203 if (blob != NULL) 4225 if (blob != NULL)
4630 4652
4631 case VAR_BLOB: 4653 case VAR_BLOB:
4632 len = blob_len(rettv->vval.v_blob); 4654 len = blob_len(rettv->vval.v_blob);
4633 if (range) 4655 if (range)
4634 { 4656 {
4635 // The resulting variable is a substring. If the indexes 4657 // The resulting variable is a sub-blob. If the indexes
4636 // are out of range the result is empty. 4658 // are out of range the result is empty.
4637 if (n1 < 0) 4659 if (n1 < 0)
4638 { 4660 {
4639 n1 = len + n1; 4661 n1 = len + n1;
4640 if (n1 < 0) 4662 if (n1 < 0)
8334 char_u *p; 8356 char_u *p;
8335 int needclr = TRUE; 8357 int needclr = TRUE;
8336 int atstart = TRUE; 8358 int atstart = TRUE;
8337 char_u numbuf[NUMBUFLEN]; 8359 char_u numbuf[NUMBUFLEN];
8338 int did_emsg_before = did_emsg; 8360 int did_emsg_before = did_emsg;
8361 int called_emsg_before = called_emsg;
8339 8362
8340 if (eap->skip) 8363 if (eap->skip)
8341 ++emsg_skip; 8364 ++emsg_skip;
8342 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 8365 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int)
8343 { 8366 {
8351 /* 8374 /*
8352 * Report the invalid expression unless the expression evaluation 8375 * Report the invalid expression unless the expression evaluation
8353 * has been cancelled due to an aborting error, an interrupt, or an 8376 * has been cancelled due to an aborting error, an interrupt, or an
8354 * exception. 8377 * exception.
8355 */ 8378 */
8356 if (!aborting() && did_emsg == did_emsg_before) 8379 if (!aborting() && did_emsg == did_emsg_before
8380 && called_emsg == called_emsg_before)
8357 EMSG2(_(e_invexpr2), p); 8381 EMSG2(_(e_invexpr2), p);
8358 need_clr_eos = FALSE; 8382 need_clr_eos = FALSE;
8359 break; 8383 break;
8360 } 8384 }
8361 need_clr_eos = FALSE; 8385 need_clr_eos = FALSE;