# HG changeset patch # User Bram Moolenaar # Date 1579118404 -3600 # Node ID 09f28c17ac58839633e19d194852e970d963d908 # Parent 271d016b8bf556917ca146b51115727ff1741d7f patch 8.2.0121: filter() and map() on blob don't work Commit: https://github.com/vim/vim/commit/49c57ce50019b667e5005ce1cfb8cdc2e48bf868 Author: Bram Moolenaar Date: Wed Jan 15 20:51:34 2020 +0100 patch 8.2.0121: filter() and map() on blob don't work Problem: filter() and map() on blob don't work. Solution: Correct the code. (closes https://github.com/vim/vim/issues/5483) diff --git a/src/list.c b/src/list.c --- a/src/list.c +++ b/src/list.c @@ -1689,6 +1689,7 @@ filter_map(typval_T *argvars, typval_T * { int i; typval_T tv; + varnumber_T val; // set_vim_var_nr() doesn't set the type set_vim_var_type(VV_KEY, VAR_NUMBER); @@ -1696,7 +1697,8 @@ filter_map(typval_T *argvars, typval_T * for (i = 0; i < b->bv_ga.ga_len; i++) { tv.v_type = VAR_NUMBER; - tv.vval.v_number = blob_get(b, i); + val = blob_get(b, i); + tv.vval.v_number = val; set_vim_var_nr(VV_KEY, idx); if (filter_map_one(&tv, expr, map, &rem) == FAIL || did_emsg) break; @@ -1705,17 +1707,21 @@ filter_map(typval_T *argvars, typval_T * emsg(_(e_invalblob)); break; } - tv.v_type = VAR_NUMBER; - blob_set(b, i, tv.vval.v_number); - if (!map && rem) + if (map) + { + if (tv.vval.v_number != val) + blob_set(b, i, tv.vval.v_number); + } + else if (rem) { char_u *p = (char_u *)argvars[0].vval.v_blob->bv_ga.ga_data; - mch_memmove(p + idx, p + i + 1, + mch_memmove(p + i, p + i + 1, (size_t)b->bv_ga.ga_len - i - 1); --b->bv_ga.ga_len; --i; } + ++idx; } } else // argvars[0].v_type == VAR_LIST diff --git a/src/testdir/test_blob.vim b/src/testdir/test_blob.vim --- a/src/testdir/test_blob.vim +++ b/src/testdir/test_blob.vim @@ -260,18 +260,22 @@ endfunc " filter() item in blob func Test_blob_filter() - let b = 0zDEADBEEF - call filter(b, 'v:val != 0xEF') - call assert_equal(0zDEADBE, b) + call assert_equal(0z, filter(0zDEADBEEF, '0')) + call assert_equal(0zADBEEF, filter(0zDEADBEEF, 'v:val != 0xDE')) + call assert_equal(0zDEADEF, filter(0zDEADBEEF, 'v:val != 0xBE')) + call assert_equal(0zDEADBE, filter(0zDEADBEEF, 'v:val != 0xEF')) + call assert_equal(0zDEADBEEF, filter(0zDEADBEEF, '1')) + call assert_equal(0z01030103, filter(0z010203010203, 'v:val != 0x02')) + call assert_equal(0zADEF, filter(0zDEADBEEF, 'v:key % 2')) endfunc " map() item in blob func Test_blob_map() - let b = 0zDEADBEEF - call map(b, 'v:val + 1') - call assert_equal(0zDFAEBFF0, b) + call assert_equal(0zDFAEBFF0, map(0zDEADBEEF, 'v:val + 1')) + call assert_equal(0z00010203, map(0zDEADBEEF, 'v:key')) + call assert_equal(0zDEAEC0F2, map(0zDEADBEEF, 'v:key + v:val')) - call assert_fails("call map(b, '[9]')", 'E978:') + call assert_fails("call map(0z00, '[9]')", 'E978:') endfunc func Test_blob_index() diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 121, +/**/ 120, /**/ 119,