113 lines
4.0 KiB
Diff
113 lines
4.0 KiB
Diff
From ac63787734fda2e294e477af52b3bd601517fa78 Mon Sep 17 00:00:00 2001
|
|
From: Christian Brabandt <cb@256bit.org>
|
|
Date: Tue, 14 Nov 2023 20:45:48 +0100
|
|
Subject: [PATCH] patch 9.0.2108: [security]: overflow with count for :s
|
|
command
|
|
|
|
Problem: [security]: overflow with count for :s command
|
|
Solution: Abort the :s command if the count is too large
|
|
|
|
If the count after the :s command is larger than what fits into a
|
|
(signed) long variable, abort with e_value_too_large.
|
|
|
|
Adds a test with INT_MAX as count and verify it correctly fails.
|
|
|
|
It seems the return value on Windows using mingw compiler wraps around,
|
|
so the initial test using :s/./b/9999999999999999999999999990 doesn't
|
|
fail there, since the count is wrapping around several times and finally
|
|
is no longer larger than 2147483647. So let's just use 2147483647 in the
|
|
test, which hopefully will always cause a failure
|
|
|
|
Signed-off-by: Christian Brabandt <cb@256bit.org>
|
|
---
|
|
runtime/doc/change.txt | 8 ++++----
|
|
runtime/doc/cmdline.txt | 3 ++-
|
|
runtime/doc/tags | 1 +
|
|
src/ex_cmds.c | 7 +++++++
|
|
src/testdir/test_substitute.vim | 1 +
|
|
5 files changed, 15 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt
|
|
index 65da9a7c6b92b..dccaa44c89922 100644
|
|
--- a/runtime/doc/change.txt
|
|
+++ b/runtime/doc/change.txt
|
|
@@ -1,4 +1,4 @@
|
|
-*change.txt* For Vim version 9.0. Last change: 2022 May 26
|
|
+*change.txt* For Vim version 9.0. Last change: 2023 Nov 15
|
|
|
|
|
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
|
@@ -635,9 +635,9 @@ For other systems the tmpnam() library function is used.
|
|
current line only. When [count] is given, replace in
|
|
[count] lines, starting with the last line in [range].
|
|
When [range] is omitted start in the current line.
|
|
- *E939*
|
|
- [count] must be a positive number. Also see
|
|
- |cmdline-ranges|.
|
|
+ *E939* *E1510*
|
|
+ [count] must be a positive number (max 2147483647)
|
|
+ Also see |cmdline-ranges|.
|
|
|
|
See |:s_flags| for [flags].
|
|
The delimiter doesn't need to be /, see
|
|
diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt
|
|
index c5d0096ddb74c..cbcf0ad274fe2 100644
|
|
--- a/runtime/doc/cmdline.txt
|
|
+++ b/runtime/doc/cmdline.txt
|
|
@@ -1,4 +1,4 @@
|
|
-*cmdline.txt* For Vim version 9.0. Last change: 2022 Jun 16
|
|
+*cmdline.txt* For Vim version 9.0. Last change: 2023 Nov 15
|
|
|
|
|
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
|
@@ -359,6 +359,7 @@ terminals)
|
|
A positive number represents the absolute index of an entry
|
|
as it is given in the first column of a :history listing.
|
|
This number remains fixed even if other entries are deleted.
|
|
+ (see |E1510|)
|
|
|
|
A negative number means the relative position of an entry,
|
|
counted from the newest entry (which has index -1) backwards.
|
|
diff --git a/runtime/doc/tags b/runtime/doc/tags
|
|
index f49061aa21064..0021ddb127793 100644
|
|
--- a/runtime/doc/tags
|
|
+++ b/runtime/doc/tags
|
|
@@ -4300,6 +4300,7 @@ E149 helphelp.txt /*E149*
|
|
E15 eval.txt /*E15*
|
|
E150 helphelp.txt /*E150*
|
|
E151 helphelp.txt /*E151*
|
|
+E1510 change.txt /*E1510*
|
|
E152 helphelp.txt /*E152*
|
|
E153 helphelp.txt /*E153*
|
|
E154 helphelp.txt /*E154*
|
|
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
|
|
index 3544092d65b11..c5f912e7ee57f 100644
|
|
--- a/src/ex_cmds.c
|
|
+++ b/src/ex_cmds.c
|
|
@@ -3940,6 +3940,13 @@ ex_substitute(exarg_T *eap)
|
|
emsg(_(e_positive_count_required));
|
|
return;
|
|
}
|
|
+ else if (i >= INT_MAX)
|
|
+ {
|
|
+ char buf[20];
|
|
+ vim_snprintf(buf, sizeof(buf), "%ld", i);
|
|
+ semsg(_(e_val_too_large), buf);
|
|
+ return;
|
|
+ }
|
|
eap->line1 = eap->line2;
|
|
eap->line2 += i - 1;
|
|
if (eap->line2 > curbuf->b_ml.ml_line_count)
|
|
diff --git a/src/testdir/test_substitute.vim b/src/testdir/test_substitute.vim
|
|
index b99d0e0058270..3ed159799f5cc 100644
|
|
--- a/src/testdir/test_substitute.vim
|
|
+++ b/src/testdir/test_substitute.vim
|
|
@@ -205,6 +205,7 @@ func Test_substitute_count()
|
|
call assert_equal(['foo foo', 'foo foo', 'foo foo', 'bar foo', 'bar foo'],
|
|
\ getline(1, '$'))
|
|
|
|
+ call assert_fails('s/./b/2147483647', 'E1510:')
|
|
bwipe!
|
|
endfunc
|
|
|