vim-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 vim/vim#3241)
9cf4b5005f
This commit is contained in:
Jan Edmund Lazo
2019-05-25 15:01:22 -04:00
parent e0348c610c
commit e664c2a158
3 changed files with 24 additions and 18 deletions

View File

@@ -1239,7 +1239,7 @@ int do_set(
} }
len++; len++;
if (opt_idx == -1) { if (opt_idx == -1) {
key = find_key_option(arg + 1); key = find_key_option(arg + 1, true);
} }
} else { } else {
len = 0; len = 0;
@@ -1253,7 +1253,7 @@ int do_set(
} }
opt_idx = findoption_len((const char *)arg, (size_t)len); opt_idx = findoption_len((const char *)arg, (size_t)len);
if (opt_idx == -1) { if (opt_idx == -1) {
key = find_key_option(arg); key = find_key_option(arg, false);
} }
} }
@@ -1986,7 +1986,7 @@ static char_u *illegal_char(char_u *errbuf, size_t errbuflen, int c)
static int string_to_key(char_u *arg) static int string_to_key(char_u *arg)
{ {
if (*arg == '<') { if (*arg == '<') {
return find_key_option(arg + 1); return find_key_option(arg + 1, true);
} }
if (*arg == '^') { if (*arg == '^') {
return Ctrl_chr(arg[1]); return Ctrl_chr(arg[1]);
@@ -4957,19 +4957,20 @@ char *set_option_value(const char *const name, const long number,
return NULL; return NULL;
} }
/* // Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number.
* 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.
int find_key_option_len(const char_u *arg, size_t len) int find_key_option_len(const char_u *arg_arg, size_t len, bool has_lt)
{ {
int key; int key = 0;
int modifiers; int modifiers;
const char_u *arg = arg_arg;
// Don't use get_special_key_code() for t_xx, we don't want it to call // Don't use get_special_key_code() for t_xx, we don't want it to call
// add_termcap_entry(). // add_termcap_entry().
if (len >= 4 && arg[0] == 't' && arg[1] == '_') { if (len >= 4 && arg[0] == 't' && arg[1] == '_') {
key = TERMCAP2KEY(arg[2], arg[3]); key = TERMCAP2KEY(arg[2], arg[3]);
} else { } else if (has_lt) {
arg--; // put arg at the '<' arg--; // put arg at the '<'
modifiers = 0; modifiers = 0;
key = find_special_key(&arg, len + 1, &modifiers, true, true, false); key = find_special_key(&arg, len + 1, &modifiers, true, true, false);
@@ -4980,9 +4981,9 @@ int find_key_option_len(const char_u *arg, size_t len)
return key; return key;
} }
static int find_key_option(const char_u *arg) static int find_key_option(const char_u *arg, bool has_lt)
{ {
return find_key_option_len(arg, STRLEN(arg)); return find_key_option_len(arg, STRLEN(arg), has_lt);
} }
/* /*

View File

@@ -29,6 +29,7 @@ source test_lambda.vim
source test_mapping.vim source test_mapping.vim
source test_menu.vim source test_menu.vim
source test_messages.vim source test_messages.vim
source test_modeline.vim
source test_move.vim source test_move.vim
source test_partial.vim source test_partial.vim
source test_popup.vim source test_popup.vim

View File

@@ -1,4 +1,8 @@
" Tests for parsing the modeline.
func Test_modeline_invalid() func Test_modeline_invalid()
" This was reading before allocated memory.
call writefile(['vi:0', 'nothing'], 'Xmodeline')
let modeline = &modeline let modeline = &modeline
set modeline set modeline
call assert_fails('set Xmodeline', 'E518:') call assert_fails('set Xmodeline', 'E518:')