Mirror of the Vim source from https://github.com/vim/vim
Revisão | d406858354a6a05d7e6ca164e7dcf8c8acc1cfc0 (tree) |
---|---|
Hora | 2021-04-09 03:15:03 |
Autor | Bram Moolenaar <Bram@vim....> |
Commiter | Bram Moolenaar |
patch 8.2.2738: extending a list with itself can give wrong result
Commit: https://github.com/vim/vim/commit/dcae51facc4d6de1edd62f0242b40972be841103
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Apr 8 20:10:10 2021 +0200
@@ -894,6 +894,7 @@ | ||
894 | 894 | { |
895 | 895 | listitem_T *item; |
896 | 896 | int todo; |
897 | + listitem_T *bef_prev; | |
897 | 898 | |
898 | 899 | // NULL list is equivalent to an empty list: nothing to do. |
899 | 900 | if (l2 == NULL || l2->lv_len == 0) |
@@ -903,9 +904,15 @@ | ||
903 | 904 | CHECK_LIST_MATERIALIZE(l1); |
904 | 905 | CHECK_LIST_MATERIALIZE(l2); |
905 | 906 | |
907 | + // When exending a list with itself, at some point we run into the item | |
908 | + // that was before "bef" and need to skip over the already inserted items | |
909 | + // to "bef". | |
910 | + bef_prev = bef == NULL ? NULL : bef->li_prev; | |
911 | + | |
906 | 912 | // We also quit the loop when we have inserted the original item count of |
907 | 913 | // the list, avoid a hang when we extend a list with itself. |
908 | - for (item = l2->lv_first; item != NULL && --todo >= 0; item = item->li_next) | |
914 | + for (item = l2->lv_first; item != NULL && --todo >= 0; | |
915 | + item = item == bef_prev ? bef : item->li_next) | |
909 | 916 | if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) |
910 | 917 | return FAIL; |
911 | 918 | return OK; |
@@ -862,6 +862,20 @@ | ||
862 | 862 | |
863 | 863 | " Extend g: dictionary with an invalid variable name |
864 | 864 | call assert_fails("call extend(g:, {'-!' : 10})", 'E461:') |
865 | + | |
866 | + " Extend a list with itself. | |
867 | + let l = [1, 5, 7] | |
868 | + call extend(l, l, 0) | |
869 | + call assert_equal([1, 5, 7, 1, 5, 7], l) | |
870 | + let l = [1, 5, 7] | |
871 | + call extend(l, l, 1) | |
872 | + call assert_equal([1, 1, 5, 7, 5, 7], l) | |
873 | + let l = [1, 5, 7] | |
874 | + call extend(l, l, 2) | |
875 | + call assert_equal([1, 5, 1, 5, 7, 7], l) | |
876 | + let l = [1, 5, 7] | |
877 | + call extend(l, l, 3) | |
878 | + call assert_equal([1, 5, 7, 1, 5, 7], l) | |
865 | 879 | endfunc |
866 | 880 | |
867 | 881 | func Test_listdict_extendnew() |
@@ -751,6 +751,8 @@ | ||
751 | 751 | static int included_patches[] = |
752 | 752 | { /* Add new patch number below this line */ |
753 | 753 | /**/ |
754 | + 2738, | |
755 | +/**/ | |
754 | 756 | 2737, |
755 | 757 | /**/ |
756 | 758 | 2736, |