vim-patch:7.4.1702

Problem:    Using freed memory when parsing 'printoptions' fails.
Solution:   Save the old options and restore them in case of an error.
            (Dominique)

4afc7c5d4a
This commit is contained in:
Michael Ennen 2016-11-24 23:39:25 -07:00 committed by James McCoy
parent 85f9f9f46d
commit 4f3bb5262c
3 changed files with 38 additions and 12 deletions

View File

@ -269,17 +269,25 @@ char_u *parse_printmbfont(void)
* Returns an error message for an illegal option, NULL otherwise. * Returns an error message for an illegal option, NULL otherwise.
* Only used for the printer at the moment... * Only used for the printer at the moment...
*/ */
static char_u *parse_list_options(char_u *option_str, option_table_T *table, int table_size) static char_u *parse_list_options(char_u *option_str, option_table_T *table,
size_t table_size)
{ {
option_table_T *old_opts;
char_u *ret = NULL;
char_u *stringp; char_u *stringp;
char_u *colonp; char_u *colonp;
char_u *commap; char_u *commap;
char_u *p; char_u *p;
int idx = 0; /* init for GCC */ size_t idx = 0; // init for GCC
int len; int len;
for (idx = 0; idx < table_size; ++idx) // Save the old values, so that they can be restored in case of an error.
table[idx].present = FALSE; old_opts = (option_table_T *)xmalloc(sizeof(option_table_T) * table_size);
for (idx = 0; idx < table_size; idx++) {
old_opts[idx] = table[idx];
table[idx].present = false;
}
/* /*
* Repeat for all comma separated parts. * Repeat for all comma separated parts.
@ -287,8 +295,10 @@ static char_u *parse_list_options(char_u *option_str, option_table_T *table, int
stringp = option_str; stringp = option_str;
while (*stringp) { while (*stringp) {
colonp = vim_strchr(stringp, ':'); colonp = vim_strchr(stringp, ':');
if (colonp == NULL) if (colonp == NULL) {
return (char_u *)N_("E550: Missing colon"); ret = (char_u *)N_("E550: Missing colon");
break;
}
commap = vim_strchr(stringp, ','); commap = vim_strchr(stringp, ',');
if (commap == NULL) if (commap == NULL)
commap = option_str + STRLEN(option_str); commap = option_str + STRLEN(option_str);
@ -299,15 +309,19 @@ static char_u *parse_list_options(char_u *option_str, option_table_T *table, int
if (STRNICMP(stringp, table[idx].name, len) == 0) if (STRNICMP(stringp, table[idx].name, len) == 0)
break; break;
if (idx == table_size) if (idx == table_size) {
return (char_u *)N_("E551: Illegal component"); ret = (char_u *)N_("E551: Illegal component");
break;
}
p = colonp + 1; p = colonp + 1;
table[idx].present = TRUE; table[idx].present = TRUE;
if (table[idx].hasnum) { if (table[idx].hasnum) {
if (!ascii_isdigit(*p)) if (!ascii_isdigit(*p)) {
return (char_u *)N_("E552: digit expected"); ret = (char_u *)N_("E552: digit expected");
break;
}
table[idx].number = getdigits_int(&p); table[idx].number = getdigits_int(&p);
} }
@ -320,7 +334,15 @@ static char_u *parse_list_options(char_u *option_str, option_table_T *table, int
++stringp; ++stringp;
} }
return NULL; if (ret != NULL) {
// Restore old options in case of error
for (idx = 0; idx < table_size; idx++) {
table[idx] = old_opts[idx];
}
}
xfree(old_opts);
return ret;
} }

View File

@ -23,6 +23,10 @@ func Test_printoptions_parsing()
set printoptions=formfeed:y set printoptions=formfeed:y
set printoptions= set printoptions=
set printoptions& set printoptions&
call assert_fails('set printoptions=paper', 'E550:')
call assert_fails('set printoptions=shredder:on', 'E551:')
call assert_fails('set printoptions=left:no', 'E552:')
endfunc endfunc
func Test_printmbfont_parsing() func Test_printmbfont_parsing()

View File

@ -742,7 +742,7 @@ static int included_patches[] = {
// 1705 NA // 1705 NA
1704, 1704,
1703, 1703,
// 1702, 1702,
1701, 1701,
1700, 1700,
1699, 1699,