From 51b0ec4d44b133c71682487484e464bc8a7fd95a Mon Sep 17 00:00:00 2001 From: yinyongkang Date: Sat, 11 May 2024 10:58:33 +0800 Subject: [PATCH] Problem with initializing the length of range() lists --- ...itializing-the-length-of-range-lists.patch | 93 +++++++++++++++++++ vim.spec | 9 +- 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 bugfix-problem-with-initializing-the-length-of-range-lists.patch diff --git a/bugfix-problem-with-initializing-the-length-of-range-lists.patch b/bugfix-problem-with-initializing-the-length-of-range-lists.patch new file mode 100644 index 0000000..dea6123 --- /dev/null +++ b/bugfix-problem-with-initializing-the-length-of-range-lists.patch @@ -0,0 +1,93 @@ +From df63da98d8dc284b1c76cfe1b17fa0acbd6094d8 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Thu, 23 Nov 2023 20:14:28 +0100 +Subject: [PATCH] patch 9.0.2123: Problem with initializing the length of + range() lists + +Problem: Problem with initializing the length of range() lists +Solution: Set length explicitly when it shouldn't contain any items + +range() may cause a wrong calculation of list length, which may later +then cause a segfault in list_find(). This is usually not a problem, +because range_list_materialize() calculates the length, when it +materializes the list. + +In addition, in list_find() when the length of the range was wrongly +initialized, it may seem to be valid, so the check for list index +out-of-bounds will not be true, because it is called before the list is +actually materialized. And so we may eventually try to access a null +pointer, causing a segfault. + +So this patch does 3 things: + +- In f_range(), when we know that the list should be empty, explicitly + set the list->lv_len value to zero. This should happen, when + start is larger than end (in case the stride is positive) or + end is larger than start when the stride is negative. + This should fix the underlying issue properly. However, + +- as a safety measure, let's check that the requested index is not + out of range one more time, after the list has been materialized + and return NULL in case it suddenly is. + +- add a few more tests to verify the behaviour. + +fixes: #13557 +closes: #13563 + +Co-authored-by: Tim Pope +Signed-off-by: Christian Brabandt +--- + src/evalfunc.c | 5 ++++- + src/list.c | 4 ++++ + src/testdir/test_functions.vim | 3 +++ + 3 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/src/evalfunc.c b/src/evalfunc.c +index 7f7914e..fa27d0d 100644 +--- a/src/evalfunc.c ++++ b/src/evalfunc.c +@@ -8646,7 +8646,10 @@ f_range(typval_T *argvars, typval_T *rettv) + list->lv_u.nonmat.lv_start = start; + list->lv_u.nonmat.lv_end = end; + list->lv_u.nonmat.lv_stride = stride; +- list->lv_len = (end - start) / stride + 1; ++ if (stride > 0 ? end < start : end > start) ++ list->lv_len = 0; ++ else ++ list->lv_len = (end - start) / stride + 1; + } + + /* +diff --git a/src/list.c b/src/list.c +index d1494c6..ce1ccaa 100644 +--- a/src/list.c ++++ b/src/list.c +@@ -415,6 +415,10 @@ list_find(list_T *l, long n) + + CHECK_LIST_MATERIALIZE(l); + ++ // range_list_materialize may reset l->lv_len ++ if (n >= l->lv_len) ++ return NULL; ++ + // When there is a cached index may start search from there. + if (l->lv_u.mat.lv_idx_item != NULL) + { +diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim +index 49b688c..0801d2b 100644 +--- a/src/testdir/test_functions.vim ++++ b/src/testdir/test_functions.vim +@@ -3052,6 +3052,9 @@ func Test_range() + " get() + call assert_equal(4, get(range(1, 10), 3)) + call assert_equal(-1, get(range(1, 10), 42, -1)) ++ call assert_equal(0, get(range(1, 0, 2), 0)) ++ call assert_equal(0, get(range(0, -1, 2), 0)) ++ call assert_equal(0, get(range(-2, -1, -2), 0)) + + " index() + call assert_equal(1, index(range(1, 5), 2)) +-- +2.41.0 + diff --git a/vim.spec b/vim.spec index 8718dc5..888c31c 100644 --- a/vim.spec +++ b/vim.spec @@ -14,7 +14,7 @@ Name: vim Epoch: 2 Version: %{baseversion}.%{patchlevel} -Release: 2 +Release: 3 Summary: Vim is a highly configurable text editor for efficiently creating and changing any kind of text. License: Vim and MIT URL: http://www.vim.org @@ -29,6 +29,7 @@ Patch0009: vim-7.4-globalsyntax.patch Patch0011: vim-8.0-copy-paste.patch Patch0012: vim-python3-tests.patch Patch0013: bugfix-security-overflow-with-count-for-s-command.patch +Patch0014: bugfix-problem-with-initializing-the-length-of-range-lists.patch Patch9000: bugfix-rm-modify-info-version.patch @@ -436,6 +437,12 @@ LC_ALL=en_US.UTF-8 make -j1 test || echo "Warning: Please check tests." %{_mandir}/man1/evim.* %changelog +* Sat May 11 2024 yinyongkang - 2:9.0.2092-3 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC: fix problem with initializing the length of range() lists + * Wed May 08 2024 yinyongkang - 2:9.0.2092-2 - Type:bugfix - ID:NA -- Gitee