mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #11996 from georg3tom/remove_restricted
Removed restricted mode - Fix #11972
This commit is contained in:
commit
4875db2e56
@ -973,7 +973,7 @@ name). This is included for backwards compatibility with version 3.0, the
|
||||
|
||||
Note: Where a file name is expected wildcards expansion is done. On Unix the
|
||||
shell is used for this, unless it can be done internally (for speed).
|
||||
Unless in |restricted-mode|, backticks work also, like in >
|
||||
Backticks work also, like in >
|
||||
:n `echo *.c`
|
||||
But expansion is only done if there are any wildcards before expanding the
|
||||
'%', '#', etc.. This avoids expanding wildcards inside a file name. If you
|
||||
|
@ -20,8 +20,8 @@ additionally sets up for viewing the differences between the arguments. >
|
||||
|
||||
nvim -d file1 file2 [file3 [file4]]
|
||||
|
||||
In addition to the |-d| argument, |-Z| and |-R| may be used for restricted
|
||||
mode and readonly mode respectively.
|
||||
In addition to the |-d| argument, |-R| may be used for readonly mode
|
||||
respectively.
|
||||
|
||||
The second and following arguments may also be a directory name. Vim will
|
||||
then append the file name of the first argument to the directory name to find
|
||||
|
@ -5698,7 +5698,6 @@ libcall({libname}, {funcname}, {argument})
|
||||
If {argument} is a number, it is passed to the function as an
|
||||
int; if {argument} is a string, it is passed as a
|
||||
null-terminated string.
|
||||
This function will fail in |restricted-mode|.
|
||||
|
||||
libcall() allows you to write your own 'plug-in' extensions to
|
||||
Vim without having to recompile the program. It is NOT a
|
||||
@ -8804,7 +8803,6 @@ system({cmd} [, {input}]) *system()* *E677*
|
||||
{cmd} is a string: 'shell' 'shellcmdflag' {cmd}
|
||||
|
||||
The resulting error code can be found in |v:shell_error|.
|
||||
This function will fail in |restricted-mode|.
|
||||
|
||||
Note that any wrong value in the options mentioned above may
|
||||
make the function fail. It has also been reported to fail
|
||||
|
@ -185,18 +185,6 @@ argument.
|
||||
the 'modifiable' and 'write' options can be set to enable
|
||||
changes and writing.
|
||||
|
||||
*-Z* *restricted-mode* *E145* *E981*
|
||||
-Z Restricted mode. All commands that make use of an external
|
||||
shell are disabled. This includes suspending with CTRL-Z,
|
||||
":sh", filtering, the system() function, backtick expansion
|
||||
and libcall().
|
||||
Also disallowed are delete(), rename(), mkdir(), jobstart(),
|
||||
etc.
|
||||
Interfaces, such as Python, Ruby and Lua, are also disabled,
|
||||
since they could be used to execute shell commands.
|
||||
Note that the user may still find a loophole to execute a
|
||||
shell command, it has only been made difficult.
|
||||
|
||||
-e *-e* *-E*
|
||||
-E Start Nvim in Ex mode |gQ|.
|
||||
|
||||
|
@ -7152,7 +7152,7 @@ void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = NULL;
|
||||
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -10418,7 +10418,7 @@ Channel *find_job(uint64_t id, bool show_error)
|
||||
|
||||
void script_host_eval(char *name, typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,7 @@ static void float_op_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
|
||||
static void api_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
{
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -862,7 +862,7 @@ static void f_chanclose(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
rettv->v_type = VAR_NUMBER;
|
||||
rettv->vval.v_number = 0;
|
||||
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -901,7 +901,7 @@ static void f_chansend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
rettv->v_type = VAR_NUMBER;
|
||||
rettv->vval.v_number = 0;
|
||||
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1480,7 +1480,7 @@ static void f_deepcopy(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
{
|
||||
rettv->vval.v_number = -1;
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1515,7 +1515,7 @@ static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
// dictwatcheradd(dict, key, funcref) function
|
||||
static void f_dictwatcheradd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
{
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1553,7 +1553,7 @@ static void f_dictwatcheradd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
// dictwatcherdel(dict, key, funcref) function
|
||||
static void f_dictwatcherdel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
{
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4798,7 +4798,7 @@ static void f_jobpid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
rettv->v_type = VAR_NUMBER;
|
||||
rettv->vval.v_number = 0;
|
||||
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4822,7 +4822,7 @@ static void f_jobresize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
rettv->v_type = VAR_NUMBER;
|
||||
rettv->vval.v_number = 0;
|
||||
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4855,7 +4855,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
rettv->v_type = VAR_NUMBER;
|
||||
rettv->vval.v_number = 0;
|
||||
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4988,7 +4988,7 @@ static void f_jobstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
rettv->v_type = VAR_NUMBER;
|
||||
rettv->vval.v_number = 0;
|
||||
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -5021,7 +5021,7 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
rettv->v_type = VAR_NUMBER;
|
||||
rettv->vval.v_number = 0;
|
||||
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
if (argvars[0].v_type != VAR_LIST || (argvars[1].v_type != VAR_NUMBER
|
||||
@ -5239,7 +5239,7 @@ static void libcall_common(typval_T *argvars, typval_T *rettv, int out_type)
|
||||
rettv->vval.v_string = NULL;
|
||||
}
|
||||
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -5942,8 +5942,9 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
int prot = 0755; // -V536
|
||||
|
||||
rettv->vval.v_number = FAIL;
|
||||
if (check_restricted() || check_secure())
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
char buf[NUMBUFLEN];
|
||||
const char *const dir = tv_get_string_buf(&argvars[0], buf);
|
||||
@ -6832,7 +6833,7 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
*/
|
||||
static void f_rename(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
{
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
rettv->vval.v_number = -1;
|
||||
} else {
|
||||
char buf[NUMBUFLEN];
|
||||
@ -7230,7 +7231,7 @@ static void f_rpcnotify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
rettv->v_type = VAR_NUMBER;
|
||||
rettv->vval.v_number = 0;
|
||||
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -7266,7 +7267,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
rettv->vval.v_number = 0;
|
||||
const int l_provider_call_nesting = provider_call_nesting;
|
||||
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -7363,7 +7364,7 @@ static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
rettv->v_type = VAR_NUMBER;
|
||||
rettv->vval.v_number = 0;
|
||||
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -7429,7 +7430,7 @@ static void f_rpcstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
rettv->v_type = VAR_NUMBER;
|
||||
rettv->vval.v_number = 0;
|
||||
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -7891,7 +7892,7 @@ static void f_serverstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = NULL; // Address of the new server
|
||||
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -7933,7 +7934,7 @@ static void f_serverstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
/// "serverstop()" function
|
||||
static void f_serverstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
{
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -10466,7 +10467,7 @@ static void f_tempname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
// "termopen(cmd[, cwd])" function
|
||||
static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
{
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1049,13 +1049,13 @@ void do_bang(int addr_count, exarg_T *eap, int forceit, int do_in, int do_out)
|
||||
int len;
|
||||
int scroll_save = msg_scroll;
|
||||
|
||||
/*
|
||||
* Disallow shell commands in restricted mode (-Z)
|
||||
* Disallow shell commands from .exrc and .vimrc in current directory for
|
||||
* security reasons.
|
||||
*/
|
||||
if (check_restricted() || check_secure())
|
||||
//
|
||||
// Disallow shell commands from .exrc and .vimrc in current directory for
|
||||
// security reasons.
|
||||
//
|
||||
if (check_secure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (addr_count == 0) { /* :! */
|
||||
msg_scroll = FALSE; /* don't scroll here */
|
||||
@ -1383,10 +1383,9 @@ do_shell(
|
||||
int flags // may be SHELL_DOOUT when output is redirected
|
||||
)
|
||||
{
|
||||
// Disallow shell commands in restricted mode (-Z)
|
||||
// Disallow shell commands from .exrc and .vimrc in current directory for
|
||||
// security reasons.
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
msg_end();
|
||||
return;
|
||||
}
|
||||
@ -3030,20 +3029,6 @@ void ex_z(exarg_T *eap)
|
||||
ex_no_reprint = true;
|
||||
}
|
||||
|
||||
// Check if the restricted flag is set.
|
||||
// If so, give an error message and return true.
|
||||
// Otherwise, return false.
|
||||
bool check_restricted(void)
|
||||
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
if (restricted) {
|
||||
EMSG(_("E145: Shell commands and some functionality not allowed"
|
||||
" in restricted mode"));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the secure flag is set (.exrc or .vimrc in current directory).
|
||||
* If so, give an error message and return TRUE.
|
||||
|
@ -62,7 +62,6 @@
|
||||
// curbuf_lock is set
|
||||
#define MODIFY 0x200000 // forbidden in non-'modifiable' buffer
|
||||
#define EXFLAGS 0x400000 // allow flags after count in argument
|
||||
#define RESTRICT 0x800000L // forbidden in restricted mode
|
||||
#define FILES (XFILE | EXTRA) // multiple extra files allowed
|
||||
#define WORD1 (EXTRA | NOSPC) // one extra word allowed
|
||||
#define FILE1 (FILES | NOSPC) // 1 file allowed, defaults to current file
|
||||
|
@ -1503,10 +1503,6 @@ static char_u * do_one_cmd(char_u **cmdlinep,
|
||||
errormsg = (char_u *)_(e_sandbox);
|
||||
goto doend;
|
||||
}
|
||||
if (restricted != 0 && (ea.argt & RESTRICT)) {
|
||||
errormsg = (char_u *)_("E981: Command not allowed in restricted mode");
|
||||
goto doend;
|
||||
}
|
||||
if (!MODIFIABLE(curbuf) && (ea.argt & MODIFY)
|
||||
// allow :put in terminals
|
||||
&& (!curbuf->terminal || ea.cmdidx != CMD_put)) {
|
||||
@ -6624,25 +6620,22 @@ static void ex_hide(exarg_T *eap)
|
||||
/// ":stop" and ":suspend": Suspend Vim.
|
||||
static void ex_stop(exarg_T *eap)
|
||||
{
|
||||
// Disallow suspending in restricted mode (-Z)
|
||||
if (!check_restricted()) {
|
||||
if (!eap->forceit) {
|
||||
autowrite_all();
|
||||
}
|
||||
apply_autocmds(EVENT_VIMSUSPEND, NULL, NULL, false, NULL);
|
||||
|
||||
// TODO(bfredl): the TUI should do this on suspend
|
||||
ui_cursor_goto(Rows - 1, 0);
|
||||
ui_call_grid_scroll(1, 0, Rows, 0, Columns, 1, 0);
|
||||
ui_flush();
|
||||
ui_call_suspend(); // call machine specific function
|
||||
|
||||
ui_flush();
|
||||
maketitle();
|
||||
resettitle(); // force updating the title
|
||||
ui_refresh(); // may have resized window
|
||||
apply_autocmds(EVENT_VIMRESUME, NULL, NULL, false, NULL);
|
||||
if (!eap->forceit) {
|
||||
autowrite_all();
|
||||
}
|
||||
apply_autocmds(EVENT_VIMSUSPEND, NULL, NULL, false, NULL);
|
||||
|
||||
// TODO(bfredl): the TUI should do this on suspend
|
||||
ui_cursor_goto(Rows - 1, 0);
|
||||
ui_call_grid_scroll(1, 0, Rows, 0, Columns, 1, 0);
|
||||
ui_flush();
|
||||
ui_call_suspend(); // call machine specific function
|
||||
|
||||
ui_flush();
|
||||
maketitle();
|
||||
resettitle(); // force updating the title
|
||||
ui_refresh(); // may have resized window
|
||||
apply_autocmds(EVENT_VIMRESUME, NULL, NULL, false, NULL);
|
||||
}
|
||||
|
||||
// ":exit", ":xit" and ":wq": Write file and quite the current window.
|
||||
|
@ -492,9 +492,6 @@ EXTERN int stdout_isatty INIT(= true);
|
||||
// volatile because it is used in a signal handler.
|
||||
EXTERN volatile int full_screen INIT(= false);
|
||||
|
||||
// When started in restricted mode (-Z).
|
||||
EXTERN int restricted INIT(= false);
|
||||
|
||||
/// Non-zero when only "safe" commands are allowed, e.g. when sourcing .exrc or
|
||||
/// .vimrc in current directory.
|
||||
EXTERN int secure INIT(= false);
|
||||
|
@ -965,7 +965,7 @@ static void typval_exec_lua(const char *lcmd, size_t lcmd_len, const char *name,
|
||||
typval_T *const args, int argcount, bool special,
|
||||
typval_T *ret_tv)
|
||||
{
|
||||
if (check_restricted() || check_secure()) {
|
||||
if (check_secure()) {
|
||||
if (ret_tv) {
|
||||
ret_tv->v_type = VAR_NUMBER;
|
||||
ret_tv->vval.v_number = 0;
|
||||
|
@ -1012,10 +1012,6 @@ static void command_line_scan(mparm_T *parmp)
|
||||
want_argument = true;
|
||||
break;
|
||||
}
|
||||
case 'Z': { // "-Z" restricted mode
|
||||
restricted = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'c': { // "-c{command}" or "-c {command}" exec command
|
||||
if (argv[0][argv_idx] != NUL) {
|
||||
|
@ -1091,8 +1091,9 @@ char_u *get_cmd_output(char_u *cmd, char_u *infile, ShellOpts flags,
|
||||
{
|
||||
char_u *buffer = NULL;
|
||||
|
||||
if (check_restricted() || check_secure())
|
||||
if (check_secure()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// get a name for the temp file
|
||||
char_u *tempname = vim_tempname();
|
||||
|
@ -150,11 +150,11 @@ int os_expand_wildcards(int num_pat, char_u **pat, int *num_file,
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// Don't allow the use of backticks in secure and restricted mode.
|
||||
if (secure || restricted) {
|
||||
// Don't allow the use of backticks in secure.
|
||||
if (secure) {
|
||||
for (i = 0; i < num_pat; i++) {
|
||||
if (vim_strchr(pat[i], '`') != NULL
|
||||
&& (check_restricted() || check_secure())) {
|
||||
&& (check_secure())) {
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
|
@ -1,103 +0,0 @@
|
||||
" Test for "rvim" or "vim -Z"
|
||||
|
||||
source shared.vim
|
||||
|
||||
"if has('win32') && has('gui')
|
||||
" " Win32 GUI shows a dialog instead of displaying the error in the last line.
|
||||
" finish
|
||||
"endif
|
||||
|
||||
func Test_restricted()
|
||||
call Run_restricted_test('!ls', 'E145:')
|
||||
endfunc
|
||||
|
||||
func Run_restricted_test(ex_cmd, error)
|
||||
let cmd = GetVimCommand('Xrestricted')
|
||||
if cmd == ''
|
||||
return
|
||||
endif
|
||||
|
||||
" Use a VimEnter autocommand to avoid that the error message is displayed in
|
||||
" a dialog with an OK button.
|
||||
call writefile([
|
||||
\ "func Init()",
|
||||
\ " silent! " . a:ex_cmd,
|
||||
\ " call writefile([v:errmsg], 'Xrestrout')",
|
||||
\ " qa!",
|
||||
\ "endfunc",
|
||||
\ "au VimEnter * call Init()",
|
||||
\ ], 'Xrestricted')
|
||||
call system(cmd . ' -Z')
|
||||
call assert_match(a:error, join(readfile('Xrestrout')))
|
||||
|
||||
call delete('Xrestricted')
|
||||
call delete('Xrestrout')
|
||||
endfunc
|
||||
|
||||
func Test_restricted_lua()
|
||||
if !has('lua')
|
||||
throw 'Skipped: Lua is not supported'
|
||||
endif
|
||||
call Run_restricted_test('lua print("Hello, Vim!")', 'E981:')
|
||||
call Run_restricted_test('luado return "hello"', 'E981:')
|
||||
call Run_restricted_test('luafile somefile', 'E981:')
|
||||
call Run_restricted_test('call luaeval("expression")', 'E145:')
|
||||
endfunc
|
||||
|
||||
func Test_restricted_mzscheme()
|
||||
if !has('mzscheme')
|
||||
throw 'Skipped: MzScheme is not supported'
|
||||
endif
|
||||
call Run_restricted_test('mzscheme statement', 'E981:')
|
||||
call Run_restricted_test('mzfile somefile', 'E981:')
|
||||
call Run_restricted_test('call mzeval("expression")', 'E145:')
|
||||
endfunc
|
||||
|
||||
func Test_restricted_perl()
|
||||
if !has('perl')
|
||||
throw 'Skipped: Perl is not supported'
|
||||
endif
|
||||
" TODO: how to make Safe mode fail?
|
||||
" call Run_restricted_test('perl system("ls")', 'E981:')
|
||||
" call Run_restricted_test('perldo system("hello")', 'E981:')
|
||||
" call Run_restricted_test('perlfile somefile', 'E981:')
|
||||
" call Run_restricted_test('call perleval("system(\"ls\")")', 'E145:')
|
||||
endfunc
|
||||
|
||||
func Test_restricted_python()
|
||||
if !has('python')
|
||||
throw 'Skipped: Python is not supported'
|
||||
endif
|
||||
call Run_restricted_test('python print "hello"', 'E981:')
|
||||
call Run_restricted_test('pydo return "hello"', 'E981:')
|
||||
call Run_restricted_test('pyfile somefile', 'E981:')
|
||||
call Run_restricted_test('call pyeval("expression")', 'E145:')
|
||||
endfunc
|
||||
|
||||
func Test_restricted_python3()
|
||||
if !has('python3')
|
||||
throw 'Skipped: Python3 is not supported'
|
||||
endif
|
||||
call Run_restricted_test('py3 print "hello"', 'E981:')
|
||||
call Run_restricted_test('py3do return "hello"', 'E981:')
|
||||
call Run_restricted_test('py3file somefile', 'E981:')
|
||||
call Run_restricted_test('call py3eval("expression")', 'E145:')
|
||||
endfunc
|
||||
|
||||
func Test_restricted_ruby()
|
||||
if !has('ruby')
|
||||
throw 'Skipped: Ruby is not supported'
|
||||
endif
|
||||
call Run_restricted_test('ruby print "Hello"', 'E981:')
|
||||
call Run_restricted_test('rubydo print "Hello"', 'E981:')
|
||||
call Run_restricted_test('rubyfile somefile', 'E981:')
|
||||
endfunc
|
||||
|
||||
func Test_restricted_tcl()
|
||||
if !has('tcl')
|
||||
throw 'Skipped: Tcl is not supported'
|
||||
endif
|
||||
call Run_restricted_test('tcl puts "Hello"', 'E981:')
|
||||
call Run_restricted_test('tcldo puts "Hello"', 'E981:')
|
||||
call Run_restricted_test('tclfile somefile', 'E981:')
|
||||
endfunc
|
Loading…
Reference in New Issue
Block a user