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:
@@ -3,13 +3,10 @@
|
||||
|
||||
print "testing shell builtins"
|
||||
|
||||
-- === __builtins table ===
|
||||
-- === __builtins is NOT in _G (internal, stored in registry) ===
|
||||
|
||||
do
|
||||
assert(type(__builtins) == "table")
|
||||
assert(type(__builtins.cd) == "function")
|
||||
assert(type(__builtins.exec) == "function")
|
||||
assert(type(__builtins.umask) == "function")
|
||||
assert(__builtins == nil, "__builtins should not be in _G")
|
||||
end
|
||||
|
||||
|
||||
@@ -117,9 +114,9 @@ end
|
||||
|
||||
-- === exec ===
|
||||
|
||||
-- exec with no command returns error
|
||||
-- exec with no command returns error (tested via backtick)
|
||||
do
|
||||
local r = __builtins.exec("exec")
|
||||
local r = `exec`
|
||||
assert(r.code == 1)
|
||||
assert(r.stderr:find("command required"),
|
||||
"expected 'command required', got: " .. r.stderr)
|
||||
@@ -127,7 +124,7 @@ end
|
||||
|
||||
-- exec nonexistent command returns error
|
||||
do
|
||||
local r = __builtins.exec("exec", "nonexistent_cmd_xyz_999")
|
||||
local r = `exec nonexistent_cmd_xyz_999`
|
||||
assert(r.code == 1)
|
||||
assert(r.stderr:find("exec:"),
|
||||
"expected exec error, got: " .. r.stderr)
|
||||
@@ -140,21 +137,4 @@ do
|
||||
end
|
||||
|
||||
|
||||
-- === builtins are overridable ===
|
||||
|
||||
do
|
||||
local old_cd = __builtins.cd
|
||||
local called = false
|
||||
__builtins.cd = function(...)
|
||||
called = true
|
||||
return old_cd(...)
|
||||
end
|
||||
local before = `pwd`.stdout:gsub("\n$", "")
|
||||
`cd /tmp`
|
||||
assert(called, "custom cd was not called")
|
||||
__builtins.cd = old_cd
|
||||
`cd ${before}`
|
||||
end
|
||||
|
||||
|
||||
print "OK"
|
||||
|
||||
Reference in New Issue
Block a user