diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-07-18 22:25:29 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-07-18 22:25:29 +0200 |
commit | 885971e2f5eabc4108e083086c1d6d0a31a2782f (patch) | |
tree | 4ecfebdc5ea8ca8c6274b76255bc06c007f9a440 | |
parent | 9ff9c7b9741b216d3dc75603e50654088dc5f55b (diff) | |
download | vim-git-885971e2f5eabc4108e083086c1d6d0a31a2782f.tar.gz |
patch 8.2.3182: Vim9: crash when using removing items from a constant listv8.2.3182
Problem: Vim9: crash when using removing items from a constant list.
(Yegappan Lakshmanan)
Solution: When a list was allocated with items copy them.
-rw-r--r-- | src/list.c | 32 | ||||
-rw-r--r-- | src/testdir/test_vim9_builtin.vim | 6 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 34 insertions, 6 deletions
diff --git a/src/list.c b/src/list.c index d138d868c..417f735e0 100644 --- a/src/list.c +++ b/src/list.c @@ -1566,12 +1566,32 @@ list_remove(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg) vimlist_remove(l, item, item2); if (rettv_list_alloc(rettv) == OK) { - l = rettv->vval.v_list; - l->lv_first = item; - l->lv_u.mat.lv_last = item2; - item->li_prev = NULL; - item2->li_next = NULL; - l->lv_len = cnt; + list_T *rl = rettv->vval.v_list; + + if (l->lv_with_items > 0) + { + // need to copy the list items and move the value + while (item != NULL) + { + li = listitem_alloc(); + if (li == NULL) + return; + li->li_tv = item->li_tv; + init_tv(&item->li_tv); + list_append(rl, li); + if (item == item2) + break; + item = item->li_next; + } + } + else + { + rl->lv_first = item; + rl->lv_u.mat.lv_last = item2; + item->li_prev = NULL; + item2->li_next = NULL; + rl->lv_len = cnt; + } } } } diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim index 638d7daa1..76987b68a 100644 --- a/src/testdir/test_vim9_builtin.vim +++ b/src/testdir/test_vim9_builtin.vim @@ -2083,6 +2083,12 @@ def Test_remote_startserver() CheckDefFailure(['remote_startserver({})'], 'E1013: Argument 1: type mismatch, expected string but got dict<unknown>') enddef +def Test_remove_const_list() + var l: list<number> = [1, 2, 3, 4] + assert_equal([1, 2], remove(l, 0, 1)) + assert_equal([3, 4], l) +enddef + def Test_remove_return_type() var l = remove({one: [1, 2], two: [3, 4]}, 'one') var res = 0 diff --git a/src/version.c b/src/version.c index 371fdcd88..6ae1d3bf0 100644 --- a/src/version.c +++ b/src/version.c @@ -756,6 +756,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3182, +/**/ 3181, /**/ 3180, |