summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-04-03 14:56:52 +0200
committerBram Moolenaar <Bram@vim.org>2016-04-03 14:56:52 +0200
commit4afc7c5d4a73340831077a02bfe1f74935e7f4a1 (patch)
tree734dacbc3a3ce4d2d07f227a16dbcc7274fce2b2
parentf9f22dbe4f90673ecce601a9dee4bb750ce3cd8f (diff)
downloadvim-git-4afc7c5d4a73340831077a02bfe1f74935e7f4a1.tar.gz
patch 7.4.1702v7.4.1702
Problem: Using freed memory when parsing 'printoptions' fails. Solution: Save the old options and restore them in case of an error. (Dominique)
-rw-r--r--src/hardcopy.c35
-rw-r--r--src/testdir/test_hardcopy.vim4
-rw-r--r--src/version.c2
3 files changed, 36 insertions, 5 deletions
diff --git a/src/hardcopy.c b/src/hardcopy.c
index 74fee2e21..f65a6dd40 100644
--- a/src/hardcopy.c
+++ b/src/hardcopy.c
@@ -189,6 +189,8 @@ parse_list_options(
option_table_T *table,
int table_size)
{
+ option_table_T *old_opts;
+ char_u *ret = NULL;
char_u *stringp;
char_u *colonp;
char_u *commap;
@@ -196,8 +198,16 @@ parse_list_options(
int idx = 0; /* init for GCC */
int len;
+ /* Save the old values, so that they can be restored in case of an error. */
+ old_opts = (option_table_T *)alloc(sizeof(option_table_T) * table_size);
+ if (old_opts == NULL)
+ return NULL;
+
for (idx = 0; idx < table_size; ++idx)
+ {
+ old_opts[idx] = table[idx];
table[idx].present = FALSE;
+ }
/*
* Repeat for all comma separated parts.
@@ -207,7 +217,10 @@ parse_list_options(
{
colonp = vim_strchr(stringp, ':');
if (colonp == NULL)
- return (char_u *)N_("E550: Missing colon");
+ {
+ ret = (char_u *)N_("E550: Missing colon");
+ break;
+ }
commap = vim_strchr(stringp, ',');
if (commap == NULL)
commap = option_str + STRLEN(option_str);
@@ -219,15 +232,20 @@ parse_list_options(
break;
if (idx == table_size)
- return (char_u *)N_("E551: Illegal component");
-
+ {
+ ret = (char_u *)N_("E551: Illegal component");
+ break;
+ }
p = colonp + 1;
table[idx].present = TRUE;
if (table[idx].hasnum)
{
if (!VIM_ISDIGIT(*p))
- return (char_u *)N_("E552: digit expected");
+ {
+ ret = (char_u *)N_("E552: digit expected");
+ break;
+ }
table[idx].number = getdigits(&p); /*advances p*/
}
@@ -240,7 +258,14 @@ parse_list_options(
++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];
+ }
+ vim_free(old_opts);
+ return ret;
}
diff --git a/src/testdir/test_hardcopy.vim b/src/testdir/test_hardcopy.vim
index 4629d17dd..ea9790d13 100644
--- a/src/testdir/test_hardcopy.vim
+++ b/src/testdir/test_hardcopy.vim
@@ -23,6 +23,10 @@ func Test_printoptions_parsing()
set printoptions=formfeed:y
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
func Test_printmbfont_parsing()
diff --git a/src/version.c b/src/version.c
index 9d6deb671..569446610 100644
--- a/src/version.c
+++ b/src/version.c
@@ -749,6 +749,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1702,
+/**/
1701,
/**/
1700,