1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
From: Bram Moolenaar <Bram@vim.org>
Date: Mon, 23 Jul 2018 04:12:03 +0200
Subject: patch 8.1.0205: invalid memory access with invalid modeline
Problem: Invalid memory access with invalid modeline.
Solution: Pass pointer limit. Add a test. (closes #3241)
(cherry picked from commit 9cf4b5005f12ce1d6692266140bdda05d0312d79)
Signed-off-by: James McCoy <jamessan@debian.org>
---
src/Makefile | 1 +
src/option.c | 17 ++++++++++-------
src/testdir/test_alot.vim | 1 +
src/testdir/test_modeline.vim | 8 ++++++++
src/version.c | 2 ++
5 files changed, 22 insertions(+), 7 deletions(-)
create mode 100644 src/testdir/test_modeline.vim
diff --git a/src/Makefile b/src/Makefile
index 38ca4cd..53683a5 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2139,6 +2139,7 @@ test_arglist \
test_messages \
test_mksession \
test_mksession_utf8 \
+ test_modeline \
test_nested_function \
test_netbeans \
test_normal \
diff --git a/src/option.c b/src/option.c
index 056292f..48bf9ce 100644
--- a/src/option.c
+++ b/src/option.c
@@ -3144,7 +3144,7 @@ static char_u *set_bool_option(int opt_idx, char_u *varp, int value, int opt_fla
static char_u *set_num_option(int opt_idx, char_u *varp, long value, char_u *errbuf, size_t errbuflen, int opt_flags);
static void check_redraw(long_u flags);
static int findoption(char_u *);
-static int find_key_option(char_u *);
+static int find_key_option(char_u *arg_arg, int has_lt);
static void showoptions(int all, int opt_flags);
static int optval_default(struct vimoption *, char_u *varp);
static void showoneopt(struct vimoption *, int opt_flags);
@@ -4279,7 +4279,7 @@ do_set(
opt_idx = findoption(arg + 1);
arg[len++] = '>'; /* restore '>' */
if (opt_idx == -1)
- key = find_key_option(arg + 1);
+ key = find_key_option(arg + 1, TRUE);
}
else
{
@@ -4297,7 +4297,7 @@ do_set(
opt_idx = findoption(arg);
arg[len] = nextchar; /* restore nextchar */
if (opt_idx == -1)
- key = find_key_option(arg);
+ key = find_key_option(arg, FALSE);
}
/* remember character after option name */
@@ -5147,7 +5147,7 @@ illegal_char(char_u *errbuf, int c)
string_to_key(char_u *arg)
{
if (*arg == '<')
- return find_key_option(arg + 1);
+ return find_key_option(arg + 1, TRUE);
if (*arg == '^')
return Ctrl_chr(arg[1]);
return *arg;
@@ -9531,12 +9531,15 @@ get_encoding_default(void)
/*
* Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number.
+ * When "has_lt" is true there is a '<' before "*arg_arg".
+ * Returns 0 when the key is not recognized.
*/
static int
-find_key_option(char_u *arg)
+find_key_option(char_u *arg_arg, int has_lt)
{
- int key;
+ int key = 0;
int modifiers;
+ char_u *arg = arg_arg;
/*
* Don't use get_special_key_code() for t_xx, we don't want it to call
@@ -9544,7 +9547,7 @@ find_key_option(char_u *arg)
*/
if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
key = TERMCAP2KEY(arg[2], arg[3]);
- else
+ else if (has_lt)
{
--arg; /* put arg at the '<' */
modifiers = 0;
diff --git a/src/testdir/test_alot.vim b/src/testdir/test_alot.vim
index 9a7c35d..9dadf6f 100644
--- a/src/testdir/test_alot.vim
+++ b/src/testdir/test_alot.vim
@@ -29,6 +29,7 @@ source test_match.vim
source test_menu.vim
source test_mapping.vim
source test_messages.vim
+source test_modeline.vim
source test_partial.vim
source test_popup.vim
source test_reltime.vim
diff --git a/src/testdir/test_modeline.vim b/src/testdir/test_modeline.vim
new file mode 100644
index 0000000..6e49577
--- /dev/null
+++ b/src/testdir/test_modeline.vim
@@ -0,0 +1,8 @@
+" Tests for parsing the modeline.
+
+func Test_invalid()
+ " This was reading before allocated memory.
+ call writefile(['vi:0', 'nothing'], 'Xmodeline')
+ call assert_fails('split Xmodeline', 'E518:')
+ bwipe!
+endfunc
diff --git a/src/version.c b/src/version.c
index 56a66d2..fc88f3d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -1195,6 +1195,8 @@ static int included_patches[] =
*/
static char *(extra_patches[]) =
{ /* Add your patch description below this line */
+/**/
+ "8.1.0205",
/**/
"8.1.0189",
/**/
|