Skip to content

Commit 6eca04e

Browse files
Millychrisbra
authored andcommitted
patch 9.1.0797: testing of options can be further improved
Problem: testing of options can be further improved Solution: split the generated option test into test_options_all.vim, add more test cases, save and restore values, fix use-after-free closes: #15894 Signed-off-by: Milly <milly.ca@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
1 parent bfe568d commit 6eca04e

9 files changed

Lines changed: 192 additions & 73 deletions

File tree

src/main.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1694,7 +1694,11 @@ getout(int exitval)
16941694
}
16951695

16961696
#ifdef FEAT_VIMINFO
1697-
if (*p_viminfo != NUL)
1697+
if (
1698+
# ifdef EXITFREE
1699+
entered_free_all_mem == FALSE &&
1700+
# endif
1701+
*p_viminfo != NUL)
16981702
// Write out the registers, history, marks etc, to the viminfo file
16991703
write_viminfo(NULL, FALSE);
17001704
#endif

src/testdir/Make_all.mak

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ NEW_TESTS = \
232232
test_normal \
233233
test_number \
234234
test_options \
235+
test_options_all \
235236
test_packadd \
236237
test_partial \
237238
test_paste \
@@ -492,6 +493,7 @@ NEW_TESTS_RES = \
492493
test_normal.res \
493494
test_number.res \
494495
test_options.res \
496+
test_options_all.res \
495497
test_packadd.res \
496498
test_partial.res \
497499
test_paste.res \

src/testdir/Make_ming.mak

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ default: nongui
2222
include Make_all.mak
2323

2424
# Explicit dependencies.
25-
test_options.res test_alot.res: opt_test.vim
25+
test_options_all.res: opt_test.vim
2626

2727
TEST_OUTFILES = $(SCRIPTS_TINY_OUT)
2828
DOSTMP = dostmp
@@ -157,7 +157,7 @@ test_gui_init.res: test_gui_init.vim
157157
$(VIMPROG) -u gui_preinit.vim -U gui_init.vim $(NO_PLUGINS) -S runtest.vim $<
158158
@$(DEL) vimcmd
159159

160-
opt_test.vim: gen_opt_test.vim ../optiondefs.h
160+
opt_test.vim: gen_opt_test.vim ../optiondefs.h ../../runtime/doc/options.txt
161161
$(VIMPROG) -e -s -u NONE $(COMMON_ARGS) --nofork -S $^
162162
@if test -f test.log; then \
163163
cat test.log; \

src/testdir/Make_mvc.mak

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ default: nongui
1616
!include Make_all.mak
1717

1818
# Explicit dependencies.
19-
test_options.res test_alot.res: opt_test.vim
19+
test_options_all.res: opt_test.vim
2020

2121
TEST_OUTFILES = $(SCRIPTS_TINY_OUT)
2222
DOSTMP = dostmp
@@ -151,7 +151,7 @@ test_gui_init.res: test_gui_init.vim
151151
$(VIMPROG) -u gui_preinit.vim -U gui_init.vim $(NO_PLUGINS) -S runtest.vim $*.vim
152152
@del vimcmd
153153

154-
opt_test.vim: gen_opt_test.vim ../optiondefs.h
154+
opt_test.vim: gen_opt_test.vim ../optiondefs.h ../../runtime/doc/options.txt
155155
$(VIMPROG) -e -s -u NONE $(COMMON_ARGS) --nofork -S $**
156156
@if exist test.log ( type test.log & exit /b 1 )
157157

src/testdir/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ default: nongui
3030
include Make_all.mak
3131

3232
# Explicit dependencies.
33-
test_options.res test_alot.res: opt_test.vim
33+
test_options_all.res: opt_test.vim
3434

3535
.SUFFIXES: .in .out .res .vim
3636

@@ -160,7 +160,7 @@ test_gui_init.res: test_gui_init.vim
160160
$(RUN_VIMTEST) -u gui_preinit.vim -U gui_init.vim $(NO_PLUGINS) -S runtest.vim $<
161161
@rm vimcmd
162162

163-
GEN_OPT_DEPS = gen_opt_test.vim ../optiondefs.h
163+
GEN_OPT_DEPS = gen_opt_test.vim ../optiondefs.h ../../runtime/doc/options.txt
164164

165165
opt_test.vim: $(GEN_OPT_DEPS)
166166
$(VIMPROG) -e -s -u NONE $(NO_INITS) --nofork --gui-dialog-file guidialog -S $(GEN_OPT_DEPS)

src/testdir/gen_opt_test.vim

Lines changed: 162 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
" Script to generate testdir/opt_test.vim from optiondefs.h
1+
" Script to generate src/testdir/opt_test.vim from src/optiondefs.h and
2+
" runtime/doc/options.txt
23

34
set cpo=&vim
45

@@ -11,19 +12,65 @@ set nomore
1112

1213
const K_KENTER = -16715
1314

15+
" Get global-local options.
16+
" "key" is full-name of the option.
17+
" "value" is the local value to switch back to the global value.
18+
b options.txt
19+
call cursor(1, 1)
20+
let global_locals = {}
21+
while search("^'[^']*'.*\\n.*|global-local", 'W')
22+
let fullname = getline('.')->matchstr("^'\\zs[^']*")
23+
let global_locals[fullname] = ''
24+
endwhile
25+
call extend(global_locals, #{
26+
\ scrolloff: -1,
27+
\ sidescrolloff: -1,
28+
\ undolevels: -12345,
29+
\})
30+
31+
" Get local-noglobal options.
32+
" "key" is full-name of the option.
33+
" "value" is no used.
34+
b options.txt
35+
call cursor(1, 1)
36+
let local_noglobals = {}
37+
while search("^'[^']*'.*\\n.*|local-noglobal", 'W')
38+
let fullname = getline('.')->matchstr("^'\\zs[^']*")
39+
let local_noglobals[fullname] = v:true
40+
endwhile
41+
42+
" Options to skip `setglobal` tests.
43+
" "key" is full-name of the option.
44+
" "value" is the reason.
45+
let skip_setglobal_reasons = #{
46+
\ iminsert: 'The global value is always overwritten by the local value',
47+
\ imsearch: 'The global value is always overwritten by the local value',
48+
\ breakindentopt: 'TODO: fix missing error handling for setglobal',
49+
\ colorcolumn: 'TODO: fix missing error handling for setglobal',
50+
\ conceallevel: 'TODO: fix missing error handling for setglobal',
51+
\ foldcolumn: 'TODO: fix missing error handling for setglobal',
52+
\ foldmethod: 'TODO: fix `setglobal fdm=` not given an error',
53+
\ iskeyword: 'TODO: fix missing error handling for setglobal',
54+
\ numberwidth: 'TODO: fix missing error handling for setglobal',
55+
\ scrolloff: 'TODO: fix missing error handling for setglobal',
56+
\ shiftwidth: 'TODO: fix missing error handling for setglobal',
57+
\ sidescrolloff: 'TODO: fix missing error handling for setglobal',
58+
\ tabstop: 'TODO: fix missing error handling for setglobal',
59+
\ termwinkey: 'TODO: fix missing error handling for setglobal',
60+
\ termwinsize: 'TODO: fix missing error handling for setglobal',
61+
\ textwidth: 'TODO: fix missing error handling for setglobal',
62+
\}
63+
1464
" The terminal size is restored at the end.
15-
" Clear out t_WS, we don't want to resize the actual terminal.
1665
let script = [
1766
\ '" DO NOT EDIT: Generated with gen_opt_test.vim',
18-
\ '" Used by test_options.vim.',
67+
\ '" Used by test_options_all.vim.',
1968
\ '',
20-
\ 'let save_columns = &columns',
21-
\ 'let save_lines = &lines',
22-
\ 'set t_WS=',
69+
\ 'scriptencoding utf-8',
2370
\ ]
2471

25-
/#define p_term
26-
let end = line('.')
72+
b optiondefs.h
73+
const end = search('#define p_term', 'nw')
2774

2875
" font name that works everywhere (hopefully)
2976
let fontname = has('win32') ? 'fixedsys' : 'fixed'
@@ -295,76 +342,132 @@ let test_values = {
295342
\ 'otherstring': [['', 'xxx'], []],
296343
\}
297344

345+
" Two lists with values: values that pre- and post-processing in test.
346+
" Clear out t_WS: we don't want to resize the actual terminal.
347+
let test_prepost = {
348+
\ 'browsedir': [["call mkdir('Xdir with space', 'D')"], []],
349+
\ 'columns': [[
350+
\ 'set t_WS=',
351+
\ 'let save_columns = &columns'
352+
\ ], [
353+
\ 'let &columns = save_columns',
354+
\ 'set t_WS&'
355+
\ ]],
356+
\ 'lines': [[
357+
\ 'set t_WS=',
358+
\ 'let save_lines = &lines'
359+
\ ], [
360+
\ 'let &lines = save_lines',
361+
\ 'set t_WS&'
362+
\ ]],
363+
\ 'verbosefile': [[], ['call delete("Xfile")']],
364+
\}
365+
298366
const invalid_options = test_values->keys()
299367
\->filter({-> v:val !~# '^other' && !exists($"&{v:val}")})
300368
if !empty(invalid_options)
301369
throw $"Invalid option name in test_values: '{invalid_options->join("', '")}'"
302370
endif
303371

304372
1
305-
/struct vimoption options
373+
call search('struct vimoption options')
306374
while 1
307-
/{"
308-
if line('.') > end
375+
if search('{"', 'W') > end
309376
break
310377
endif
311378
let line = getline('.')
312-
let name = substitute(line, '.*{"\([^"]*\)".*', '\1', '')
379+
let fullname = substitute(line, '.*{"\([^"]*\)".*', '\1', '')
313380
let shortname = substitute(line, '.*"\([^"]*\)".*', '\1', '')
314381

315-
if has_key(test_values, name)
316-
let a = test_values[name]
317-
elseif line =~ 'P_NUM'
318-
let a = test_values['othernum']
319-
else
320-
let a = test_values['otherstring']
382+
let [valid_values, invalid_values] = test_values[
383+
\ has_key(test_values, fullname) ? fullname
384+
\ : line =~ 'P_NUM' ? 'othernum'
385+
\ : 'otherstring']
386+
387+
if empty(valid_values) && empty(invalid_values)
388+
continue
321389
endif
322-
if len(a[0]) > 0 || len(a[1]) > 0
323-
if name == 'browsedir'
324-
call add(script, 'call mkdir("Xdir with space")')
325-
endif
326390

327-
if line =~ 'P_BOOL'
328-
call add(script, 'set ' . name)
329-
call add(script, 'set ' . shortname)
330-
call add(script, 'set no' . name)
331-
call add(script, 'set no' . shortname)
332-
else
333-
for val in a[0]
334-
call add(script, 'set ' . name . '=' . val)
335-
call add(script, 'set ' . shortname . '=' . val)
336-
endfor
391+
call add(script, $"func Test_opt_set_{fullname}()")
392+
call add(script, $"if exists('+{fullname}') && execute('set!') =~# '\\n..{fullname}\\([=\\n]\\|$\\)'")
393+
call add(script, $"let l:saved = [&g:{fullname}, &l:{fullname}]")
394+
call add(script, 'endif')
395+
396+
let [pre_processing, post_processing] = get(test_prepost, fullname, [[], []])
397+
let script += pre_processing
337398

338-
" setting an option can only fail when it's implemented.
339-
call add(script, "if exists('+" . name . "')")
340-
for val in a[1]
341-
call add(script, "silent! call assert_fails('set " . name . "=" . val . "')")
342-
call add(script, "silent! call assert_fails('set " . shortname . "=" . val . "')")
399+
if line =~ 'P_BOOL'
400+
for opt in [fullname, shortname]
401+
for cmd in ['set', 'setlocal', 'setglobal']
402+
call add(script, $'{cmd} {opt}')
403+
call add(script, $'{cmd} no{opt}')
404+
call add(script, $'{cmd} inv{opt}')
405+
call add(script, $'{cmd} {opt}!')
343406
endfor
344-
call add(script, "endif")
345-
endif
407+
endfor
408+
else " P_NUM || P_STRING
409+
" Normal tests
410+
for opt in [fullname, shortname]
411+
for cmd in ['set', 'setlocal', 'setglobal']
412+
for val in valid_values
413+
if local_noglobals->has_key(fullname) && cmd ==# 'setglobal'
414+
" Skip `:setglobal {option}={val}` for local-noglobal option.
415+
" It has no effect.
416+
let pre = '" Skip local-noglobal: '
417+
else
418+
let pre = ''
419+
endif
420+
call add(script, $'{pre}{cmd} {opt}={val}')
421+
endfor
422+
endfor
423+
" Testing to clear the local value and switch back to the global value.
424+
if global_locals->has_key(fullname)
425+
let swichback_val = global_locals[fullname]
426+
call add(script, $'setlocal {opt}={swichback_val}')
427+
endif
428+
endfor
346429

347-
" cannot change 'termencoding' in GTK
348-
if name != 'termencoding' || !has('gui_gtk')
349-
call add(script, 'set ' . name . '&')
350-
call add(script, 'set ' . shortname . '&')
351-
endif
352-
if name == 'browsedir'
353-
call add(script, 'call delete("Xdir with space", "d")')
354-
elseif name == 'verbosefile'
355-
call add(script, 'call delete("Xfile")')
356-
endif
430+
" Failure tests
431+
" Setting an option can only fail when it's implemented.
432+
call add(script, $"if exists('+{fullname}')")
433+
for opt in [fullname, shortname]
434+
for cmd in ['set', 'setlocal', 'setglobal']
435+
for val in invalid_values
436+
if val is# global_locals->get(fullname, {}) && cmd ==# 'setlocal'
437+
" Skip setlocal switchback-value to global-local option. It will
438+
" not result in failure.
439+
let pre = '" Skip global-local: '
440+
elseif local_noglobals->has_key(fullname) && cmd ==# 'setglobal'
441+
" Skip setglobal to local-noglobal option. It will not result in
442+
" failure.
443+
let pre = '" Skip local-noglobal: '
444+
elseif skip_setglobal_reasons->has_key(fullname) && cmd ==# 'setglobal'
445+
" Skip setglobal to reasoned option. It will not result in failure.
446+
let reason = skip_setglobal_reasons[fullname]
447+
let pre = $'" Skip {reason}: '
448+
else
449+
let pre = ''
450+
endif
451+
let cmdline = $'{cmd} {opt}={val}'
452+
call add(script, $"{pre}silent! call assert_fails({string(cmdline)})")
453+
endfor
454+
endfor
455+
endfor
456+
call add(script, "endif")
457+
endif
357458

358-
if name == 'more'
359-
call add(script, 'set nomore')
360-
elseif name == 'lines'
361-
call add(script, 'let &lines = save_lines')
362-
endif
459+
" Cannot change 'termencoding' in GTK
460+
if fullname != 'termencoding' || !has('gui_gtk')
461+
call add(script, $'set {fullname}&')
462+
call add(script, $'set {shortname}&')
463+
call add(script, $"if exists('l:saved')")
464+
call add(script, $"let [&g:{fullname}, &l:{fullname}] = l:saved")
465+
call add(script, 'endif')
363466
endif
364-
endwhile
365467

366-
call add(script, 'let &columns = save_columns')
367-
call add(script, 'let &lines = save_lines')
468+
let script += post_processing
469+
call add(script, 'endfunc')
470+
endwhile
368471

369472
call writefile(script, 'opt_test.vim')
370473

@@ -381,3 +484,5 @@ endtry
381484
endif
382485

383486
qa!
487+
488+
" vim:sw=2:ts=8:noet:nolist:nosta:

src/testdir/test_options.vim

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ source shared.vim
44
source check.vim
55
source view_util.vim
66

7+
scriptencoding utf-8
8+
79
func Test_whichwrap()
810
set whichwrap=b,s
911
call assert_equal('b,s', &whichwrap)
@@ -1037,15 +1039,6 @@ func Test_set_all_one_column()
10371039
call assert_equal(sort(copy(options)), options)
10381040
endfunc
10391041

1040-
func Test_set_values()
1041-
" opt_test.vim is generated from ../optiondefs.h using gen_opt_test.vim
1042-
if filereadable('opt_test.vim')
1043-
source opt_test.vim
1044-
else
1045-
throw 'Skipped: opt_test.vim does not exist'
1046-
endif
1047-
endfunc
1048-
10491042
func Test_renderoptions()
10501043
" Only do this for Windows Vista and later, fails on Windows XP and earlier.
10511044
" Doesn't hurt to do this on a non-Windows system.

src/testdir/test_options_all.vim

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
" Test for options
2+
3+
" opt_test.vim is generated from src/optiondefs.h and runtime/doc/options.txt
4+
" using gen_opt_test.vim
5+
if filereadable('opt_test.vim')
6+
source opt_test.vim
7+
else
8+
func Test_set_values()
9+
throw 'Skipped: opt_test.vim does not exist'
10+
endfunc
11+
endif
12+
13+
" vim: shiftwidth=2 sts=2 expandtab

src/version.c

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

705705
static int included_patches[] =
706706
{ /* Add new patch number below this line */
707+
/**/
708+
797,
707709
/**/
708710
796,
709711
/**/

0 commit comments

Comments
 (0)