Mercurial > vim
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; |