]> granicus.if.org Git - vim/commitdiff
patch 7.4.1702 v7.4.1702
authorBram Moolenaar <Bram@vim.org>
Sun, 3 Apr 2016 12:56:52 +0000 (14:56 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 3 Apr 2016 12:56:52 +0000 (14:56 +0200)
Problem:    Using freed memory when parsing 'printoptions' fails.
Solution:   Save the old options and restore them in case of an error.
            (Dominique)

src/hardcopy.c
src/testdir/test_hardcopy.vim
src/version.c

index 74fee2e214550406f33d745f565fdf037e162df7..f65a6dd40a50c27018db07a56bd9c1c01ddf4df9 100644 (file)
@@ -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;
 }
 
 
index 4629d17dd22bdf199f9591f2047ca05bdf82e9b4..ea9790d134180a69cc7d860748aaff4949ec33a5 100644 (file)
@@ -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()
index 9d6deb67104cf146441ffb902518ddfa9144db8e..569446610cb097375f617456058ae7bbdf6cce47 100644 (file)
@@ -748,6 +748,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1702,
 /**/
     1701,
 /**/