static int os_execute(lua_State * L) { int allow = 0; int ret = 1; char *safecmd = NULL; char *cmdname = NULL; const char *cmd = luaL_optstring(L, 1, NULL); if (cmd == NULL) { /* pretend we are \.{\\pdfshellescape} */ if (shellenabledp <= 0) { lua_pushinteger(L, 0); } else if (restrictedshell == 0) { lua_pushinteger(L, 1); } else { lua_pushinteger(L, 2); } return 1; } if (shellenabledp <= 0) { lua_pushnil(L); lua_pushstring(L, "All command execution disabled."); return 2; } /* If restrictedshell == 0, any command is allowed. */ if (restrictedshell == 0) allow = 1; else allow = shell_cmd_is_allowed(cmd, &safecmd, &cmdname); if (allow == 1) { lua_pushinteger(L, system(cmd)); } else if (allow == 2) { lua_pushinteger(L, system(safecmd)); } else { lua_pushnil(L); ret = 2; if (allow == 0) lua_pushstring(L, "Command execution disabled via shell_escape='p'"); else /* allow == -1 */ lua_pushstring(L, "Quoting error in system command line."); } if (safecmd) free(safecmd); if (cmdname) free(cmdname); return ret; }
static int io_popen(lua_State * L) { int ret = 1; char *safecmd = NULL; char *cmdname = NULL; int allow = 0; const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); LStream *p = newprefile(L); if (shellenabledp <= 0) { lua_pushnil(L); lua_pushliteral(L, "All command execution is disabled"); return 2; } /* If restrictedshell == 0, any command is allowed. */ if (restrictedshell == 0) allow = 1; else allow = shell_cmd_is_allowed(filename, &safecmd, &cmdname); if (allow == 1) { p->f = lua_popen(L, filename, mode); p->closef = &io_pclose; ret = (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; } else if (allow == 2) { p->f = lua_popen(L, safecmd, mode); p->closef = &io_pclose; ret = (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; } else if (allow == 0) { lua_pushnil(L); lua_pushliteral(L, "Command execution disabled via shell_escape='p'"); ret = 2; } else { lua_pushnil(L); lua_pushliteral(L, "Bad command line quoting"); ret = 2; } return ret; }
static int io_popen(lua_State * L) { int ret = 1; char *safecmd = NULL; char *cmdname = NULL; int allow = 0; const char *cmd = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "rb"); FILE **pf = newfile(L); if (shellenabledp <= 0) { lua_pushnil(L); lua_pushliteral(L, "All command execution is disabled"); return 2; } /* If restrictedshell == 0, any command is allowed. */ if (restrictedshell == 0) allow = 1; else allow = shell_cmd_is_allowed(cmd, &safecmd, &cmdname); if (allow == 1) { *pf = lua_popen(L, cmd, mode); ret = (*pf == NULL) ? pushresult(L, 0, cmd) : 1; } else if (allow == 2) { *pf = lua_popen(L, safecmd, mode); ret = (*pf == NULL) ? pushresult(L, 0, safecmd) : 1; } else if (allow == 0) { lua_pushnil(L); lua_pushliteral(L, "Command execution disabled via shell_escape='p'"); ret = 2; } else { lua_pushnil(L); lua_pushliteral(L, "Bad command line quoting"); ret = 2; } return ret; }
static int os_spawn(lua_State * L) { int allow = 0; const char *maincmd = NULL; char *runcmd = NULL; char *safecmd = NULL, *cmdname = NULL; char **cmdline = NULL; char **envblock = NULL; int i; if (lua_gettop(L) != 1) { lua_pushnil(L); lua_pushliteral(L, "invalid arguments passed"); return 2; } if (shellenabledp <= 0) { lua_pushnil(L); lua_pushliteral(L, "All command execution disabled."); return 2; } if (lua_type(L, 1) == LUA_TSTRING) { maincmd = lua_tostring(L, 1); cmdline = do_split_command(maincmd, &runcmd); } else if (lua_type(L, 1) == LUA_TTABLE) { cmdline = do_flatten_command(L, &runcmd); } /* If restrictedshell == 0, any command is allowed. */ /* this is a little different from \write18/ os.execute processing * because it does not test for commands with fixed arguments, * but I am not so eager to attempt to fix that. Just document * that os.exec() checks only the command name. */ if (restrictedshell == 0) { allow = 1; } else { const char *theruncmd = runcmd; allow = shell_cmd_is_allowed(theruncmd, &safecmd, &cmdname); } if (allow > 0 && cmdline != NULL && runcmd != NULL) { if (allow == 2) i = spawn_command(safecmd, cmdline, envblock); else i = spawn_command(runcmd, cmdline, envblock); if (safecmd) free(safecmd); if (cmdname) free(cmdname); if (i == 0) { lua_pushinteger(L, i); return 1; } else if (i == -1) { /* this branch covers WIN32 as well as fork() and waitpid() errors */ do_error_return(strerror(errno), errno); #ifndef _WIN32 } else if (i == INVALID_RET_E2BIG) { do_error_return(strerror(E2BIG), i); } else if (i == INVALID_RET_ENOENT) { do_error_return(strerror(ENOENT), i); } else if (i == INVALID_RET_ENOEXEC) { do_error_return(strerror(ENOEXEC), i); } else if (i == INVALID_RET_ENOMEM) { do_error_return(strerror(ENOMEM), i); } else if (i == INVALID_RET_ETXTBSY) { do_error_return(strerror(ETXTBSY), i); } else if (i == INVALID_RET_UNKNOWN) { do_error_return("execution failed", i); } else if (i == INVALID_RET_INTR) { do_error_return("execution interrupted", i); #endif } else { lua_pushinteger(L, i); return 1; } } if (safecmd) free(safecmd); if (cmdname) free(cmdname); if (allow == 0) { lua_pushnil(L); lua_pushliteral(L, "Command execution disabled via shell_escape='p'"); return 2; } lua_pushnil(L); lua_pushliteral(L, "invalid command line passed"); return 2; }
static int os_exec(lua_State * L) { int allow = 0; const char *maincmd = NULL; char *runcmd = NULL; char *safecmd = NULL, *cmdname = NULL; char **cmdline = NULL; char **envblock = NULL; if (lua_gettop(L) != 1) { lua_pushnil(L); lua_pushliteral(L, "invalid arguments passed"); return 2; } if (shellenabledp <= 0) { lua_pushnil(L); lua_pushliteral(L, "All command execution disabled."); return 2; } if (lua_type(L, 1) == LUA_TSTRING) { maincmd = lua_tostring(L, 1); cmdline = do_split_command(maincmd, &runcmd); } else if (lua_type(L, 1) == LUA_TTABLE) { cmdline = do_flatten_command(L, &runcmd); } /* If restrictedshell == 0, any command is allowed. */ /* this is a little different from \write18/ os.execute processing * because it does not test for commands with fixed arguments, * but I am not so eager to attempt to fix that. Just document * that os.exec() checks only the command name. */ if (restrictedshell == 0) { allow = 1; } else { const char *theruncmd = runcmd; allow = shell_cmd_is_allowed(theruncmd, &safecmd, &cmdname); } if (allow > 0 && cmdline != NULL && runcmd != NULL) { #if defined(_WIN32) && DONT_REALLY_EXIT if (allow == 2) exec_command(safecmd, cmdline, envblock); else exec_command(runcmd, cmdline, envblock); #else { int r; if (allow == 2) r = exec_command(safecmd, cmdline, envblock); else r = exec_command(runcmd, cmdline, envblock); if (r == -1) { lua_pushnil(L); lua_pushfstring(L, "%s: %s", runcmd, strerror(errno)); lua_pushinteger(L, errno); return 3; } } #endif } if (safecmd) free(safecmd); if (cmdname) free(cmdname); if (allow == 0) { lua_pushnil(L); lua_pushliteral(L, "Command execution disabled via shell_escape='p'"); return 2; } lua_pushnil(L); lua_pushliteral(L, "invalid command line passed"); return 2; }