summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/list.c9
-rw-r--r--src/testdir/test_listdict.vim14
-rw-r--r--src/version.c2
3 files changed, 24 insertions, 1 deletions
diff --git a/src/list.c b/src/list.c
index 873f9e63d..76327abc8 100644
--- a/src/list.c
+++ b/src/list.c
@@ -894,6 +894,7 @@ list_extend(list_T *l1, list_T *l2, listitem_T *bef)
{
listitem_T *item;
int todo;
+ listitem_T *bef_prev;
// NULL list is equivalent to an empty list: nothing to do.
if (l2 == NULL || l2->lv_len == 0)
@@ -903,9 +904,15 @@ list_extend(list_T *l1, list_T *l2, listitem_T *bef)
CHECK_LIST_MATERIALIZE(l1);
CHECK_LIST_MATERIALIZE(l2);
+ // When exending a list with itself, at some point we run into the item
+ // that was before "bef" and need to skip over the already inserted items
+ // to "bef".
+ bef_prev = bef == NULL ? NULL : bef->li_prev;
+
// We also quit the loop when we have inserted the original item count of
// the list, avoid a hang when we extend a list with itself.
- for (item = l2->lv_first; item != NULL && --todo >= 0; item = item->li_next)
+ for (item = l2->lv_first; item != NULL && --todo >= 0;
+ item = item == bef_prev ? bef : item->li_next)
if (list_insert_tv(l1, &item->li_tv, bef) == FAIL)
return FAIL;
return OK;
diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim
index 051a37c3a..1b0796d81 100644
--- a/src/testdir/test_listdict.vim
+++ b/src/testdir/test_listdict.vim
@@ -862,6 +862,20 @@ func Test_listdict_extend()
" Extend g: dictionary with an invalid variable name
call assert_fails("call extend(g:, {'-!' : 10})", 'E461:')
+
+ " Extend a list with itself.
+ let l = [1, 5, 7]
+ call extend(l, l, 0)
+ call assert_equal([1, 5, 7, 1, 5, 7], l)
+ let l = [1, 5, 7]
+ call extend(l, l, 1)
+ call assert_equal([1, 1, 5, 7, 5, 7], l)
+ let l = [1, 5, 7]
+ call extend(l, l, 2)
+ call assert_equal([1, 5, 1, 5, 7, 7], l)
+ let l = [1, 5, 7]
+ call extend(l, l, 3)
+ call assert_equal([1, 5, 7, 1, 5, 7], l)
endfunc
func Test_listdict_extendnew()
diff --git a/src/version.c b/src/version.c
index 1a1f23784..452565c1f 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2738,
+/**/
2737,
/**/
2736,