Hide shell functions from _G using upvalues on the main chunk
Store __command, __interactive, __getenv, __setenv as upvalues populated by lua_load() from the registry, keeping them invisible to user code while accessible to the parser's codegen.
This commit is contained in:
47
lcmd.c
47
lcmd.c
@@ -874,15 +874,21 @@ static int exec_pipeline (lua_State *L, char **stages, int nstages,
|
||||
*/
|
||||
static int try_builtin (lua_State *L, ParsedArgs *pa) {
|
||||
int i;
|
||||
if (lua_getglobal(L, "__builtins") != LUA_TTABLE) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_LUSH);
|
||||
if (!lua_istable(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
return 0;
|
||||
}
|
||||
if (lua_getfield(L, -1, pa->argv[0]) != LUA_TFUNCTION) {
|
||||
if (lua_getfield(L, -1, "builtins") != LUA_TTABLE) {
|
||||
lua_pop(L, 2);
|
||||
return 0;
|
||||
}
|
||||
lua_remove(L, -2); /* remove __builtins, keep function */
|
||||
if (lua_getfield(L, -1, pa->argv[0]) != LUA_TFUNCTION) {
|
||||
lua_pop(L, 3);
|
||||
return 0;
|
||||
}
|
||||
lua_remove(L, -2); /* remove builtins table */
|
||||
lua_remove(L, -2); /* remove lush table */
|
||||
for (i = 0; i < pa->argc; i++)
|
||||
lua_pushstring(L, pa->argv[i]);
|
||||
lua_call(L, pa->argc, 1);
|
||||
@@ -890,9 +896,9 @@ static int try_builtin (lua_State *L, ParsedArgs *pa) {
|
||||
}
|
||||
|
||||
|
||||
/* ===== luaB_command ===== */
|
||||
/* ===== lushCmd_command ===== */
|
||||
|
||||
int luaB_command (lua_State *L) {
|
||||
int lushCmd_command (lua_State *L) {
|
||||
const char *cmd = luaL_checkstring(L, 1);
|
||||
char *stages[MAX_PIPELINE_STAGES];
|
||||
int nstages;
|
||||
@@ -1033,9 +1039,9 @@ int luaB_command (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
/* ===== luaB_interactive ===== */
|
||||
/* ===== lushCmd_interactive ===== */
|
||||
|
||||
int luaB_interactive (lua_State *L) {
|
||||
int lushCmd_interactive (lua_State *L) {
|
||||
const char *cmd = luaL_checkstring(L, 1);
|
||||
char *stages[MAX_PIPELINE_STAGES];
|
||||
int nstages;
|
||||
@@ -1142,3 +1148,30 @@ int luaB_interactive (lua_State *L) {
|
||||
|
||||
return 0; /* void — no Lua return values */
|
||||
}
|
||||
|
||||
|
||||
/* ===== lushCmd_getenv ===== */
|
||||
|
||||
int lushCmd_getenv (lua_State *L) {
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
const char *val = getenv(name);
|
||||
if (val == NULL)
|
||||
lua_pushnil(L);
|
||||
else
|
||||
lua_pushstring(L, val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ===== lushCmd_setenv ===== */
|
||||
|
||||
int lushCmd_setenv (lua_State *L) {
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
if (lua_isnoneornil(L, 2))
|
||||
unsetenv(name);
|
||||
else {
|
||||
const char *val = luaL_tolstring(L, 2, NULL);
|
||||
setenv(name, val, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user