int save_State = State;
int retval;
int is_cpt_function = (cb != NULL);
+ int use_sandbox = is_cpt_function
+ && was_set_insecurely(curwin,
+ (char_u *)"complete", OPT_LOCAL);
if (!is_cpt_function)
{
// switching to another window, it should not be needed and may end up in
// Insert mode in another buffer.
++textlock;
+ if (use_sandbox)
+ ++sandbox;
retval = call_callback(cb, 0, &rettv, 2, args);
+ if (use_sandbox)
+ --sandbox;
// Call a function, which returns a list or dict.
if (retval == OK)
pos_T pos;
int save_State = State;
int is_cpt_function = (cb != NULL);
+ int use_sandbox = is_cpt_function
+ && was_set_insecurely(curwin,
+ (char_u *)"complete", OPT_LOCAL);
if (!is_cpt_function)
{
args[2].v_type = VAR_UNKNOWN;
pos = curwin->w_cursor;
++textlock;
+ if (use_sandbox)
+ ++sandbox;
col = call_callback_retnr(cb, 2, args);
+ if (use_sandbox)
+ --sandbox;
--textlock;
State = save_State;
call s:modeline_fails('titlestring', 'titlestring=Something()', 'E992:')
endfunc
+func Test_modeline_complete_uses_sandbox()
+ let modeline = &modeline
+ let modelineexpr = &modelineexpr
+ let modelinestrict = &modelinestrict
+
+ func! ModelineCompletePwnFindstart(findstart, base)
+ if a:findstart
+ call writefile(['findstart'], 'Xmodeline_complete_proof')
+ return 0
+ endif
+ return ['match']
+ endfunc
+
+ func! ModelineCompletePwnMatches(findstart, base)
+ if a:findstart
+ return 0
+ endif
+ call writefile(['matches'], 'Xmodeline_complete_proof')
+ return ['match']
+ endfunc
+
+ try
+ set modeline modelineexpr nomodelinestrict
+
+ call writefile([
+ \ 'vim: set complete=FModelineCompletePwnFindstart :',
+ \ 'body',
+ \ ], 'Xmodeline_complete_attack', 'D')
+ call delete('Xmodeline_complete_proof')
+ edit Xmodeline_complete_attack
+ call cursor(2, 1)
+ call assert_fails('call feedkeys("i\<C-N>\<Esc>", "xt")', 'E48:')
+ call assert_false(filereadable('Xmodeline_complete_proof'))
+ bwipe!
+
+ call writefile([
+ \ 'vim: set complete=FModelineCompletePwnMatches :',
+ \ 'body',
+ \ ], 'Xmodeline_complete_attack', 'D')
+ call delete('Xmodeline_complete_proof')
+ edit Xmodeline_complete_attack
+ call cursor(2, 1)
+ call assert_fails('call feedkeys("i\<C-N>\<Esc>", "xt")', 'E48:')
+ call assert_false(filereadable('Xmodeline_complete_proof'))
+ bwipe!
+ finally
+ let &modeline = modeline
+ let &modelineexpr = modelineexpr
+ let &modelinestrict = modelinestrict
+ call delete('Xmodeline_complete_proof')
+ delfunc ModelineCompletePwnFindstart
+ delfunc ModelineCompletePwnMatches
+ endtry
+endfunc
+
func Test_modeline_setoption_verbose()
let modeline = &modeline
set modeline