Skip to content

Commit 4afc7c5

Browse files
committed
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)
1 parent f9f22db commit 4afc7c5

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

src/hardcopy.c

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,15 +189,25 @@ parse_list_options(
189189
option_table_T *table,
190190
int table_size)
191191
{
192+
option_table_T *old_opts;
193+
char_u *ret = NULL;
192194
char_u *stringp;
193195
char_u *colonp;
194196
char_u *commap;
195197
char_u *p;
196198
int idx = 0; /* init for GCC */
197199
int len;
198200

201+
/* Save the old values, so that they can be restored in case of an error. */
202+
old_opts = (option_table_T *)alloc(sizeof(option_table_T) * table_size);
203+
if (old_opts == NULL)
204+
return NULL;
205+
199206
for (idx = 0; idx < table_size; ++idx)
207+
{
208+
old_opts[idx] = table[idx];
200209
table[idx].present = FALSE;
210+
}
201211

202212
/*
203213
* Repeat for all comma separated parts.
@@ -207,7 +217,10 @@ parse_list_options(
207217
{
208218
colonp = vim_strchr(stringp, ':');
209219
if (colonp == NULL)
210-
return (char_u *)N_("E550: Missing colon");
220+
{
221+
ret = (char_u *)N_("E550: Missing colon");
222+
break;
223+
}
211224
commap = vim_strchr(stringp, ',');
212225
if (commap == NULL)
213226
commap = option_str + STRLEN(option_str);
@@ -219,15 +232,20 @@ parse_list_options(
219232
break;
220233

221234
if (idx == table_size)
222-
return (char_u *)N_("E551: Illegal component");
223-
235+
{
236+
ret = (char_u *)N_("E551: Illegal component");
237+
break;
238+
}
224239
p = colonp + 1;
225240
table[idx].present = TRUE;
226241

227242
if (table[idx].hasnum)
228243
{
229244
if (!VIM_ISDIGIT(*p))
230-
return (char_u *)N_("E552: digit expected");
245+
{
246+
ret = (char_u *)N_("E552: digit expected");
247+
break;
248+
}
231249

232250
table[idx].number = getdigits(&p); /*advances p*/
233251
}
@@ -240,7 +258,14 @@ parse_list_options(
240258
++stringp;
241259
}
242260

243-
return NULL;
261+
if (ret != NULL)
262+
{
263+
/* Restore old options in case of error */
264+
for (idx = 0; idx < table_size; ++idx)
265+
table[idx] = old_opts[idx];
266+
}
267+
vim_free(old_opts);
268+
return ret;
244269
}
245270

246271

src/testdir/test_hardcopy.vim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ func Test_printoptions_parsing()
2323
set printoptions=formfeed:y
2424
set printoptions=
2525
set printoptions&
26+
27+
call assert_fails('set printoptions=paper', 'E550:')
28+
call assert_fails('set printoptions=shredder:on', 'E551:')
29+
call assert_fails('set printoptions=left:no', 'E552:')
2630
endfunc
2731

2832
func Test_printmbfont_parsing()

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,8 @@ static char *(features[]) =
748748

749749
static int included_patches[] =
750750
{ /* Add new patch number below this line */
751+
/**/
752+
1702,
751753
/**/
752754
1701,
753755
/**/

0 commit comments

Comments
 (0)