We sometimes need to restrict the runtime environment of lua code, or prevent users from accessing some global functions of lua. the lua language does not have access control for Members like C ++, C #, and Java. however, lua provides the setfenv function to flexibly handle various permissions.
Read the code.
1: -- create sandbox
2: function SpawnSandBox ()
3:
4: local SandBoxGlobals = {}
5:
6: -- add basic functions
7: SandBoxGlobals. print = print
8: SandBoxGlobals. table = table
9: SandBoxGlobals. string = string
10: SandBoxGlobals. math = math
11: SandBoxGlobals. assert = assert
12: SandBoxGlobals. getmetatable = getmetatable
13: SandBoxGlobals. ipairs = ipairs
14: SandBoxGlobals. pairs = pairs
15: SandBoxGlobals. pcall = pcall
16: SandBoxGlobals. setmetatable = setmetatable
17: SandBoxGlobals. tostring = tostring
18: SandBoxGlobals. tonumber = tonumber
19: SandBoxGlobals. type = type
20: SandBoxGlobals. unpack = unpack
21: SandBoxGlobals. collectgarbage = collectgarbage
22: SandBoxGlobals. _ G = SandBoxGlobals
23:
24: return SandBoxGlobals
25: end
26:
27: -- execute the script in the sandbox. If an error occurs, an error is returned. nil indicates that the error is correct.
28: function ExecuteInSandBox (SandBox, Script)
29:
30: local ScriptFunc, CompileError = loadstring (Script)
31:
32: if CompileError then
33: return CompileError
34: end
35:
36: setfenv (ScriptFunc, SandBox)
37:
38: local Result, RuntimeError = pcall (ScriptFunc)
39: if RuntimeError then
40: return RuntimeError
41: end
42:
43: return nil
44: end
45:
46: function ProtectedFunction ()
47: print ("protected func ")
48: end
49:
50:
51: local SandBox = SpawnSandBox ()
52:
53:
54: print ("Response =", ExecuteInSandBox (SandBox, "table. foreach (_ G, print )"))
55:
56: print ("Response =", ExecuteInSandBox (SandBox, "ProtectedFunction ()"))
57:
58: SandBox. ProtectedFunction = ProtectedFunction
59:
60: print ("Response =", ExecuteInSandBox (SandBox, "ProtectedFunction ()"))
The execution result of 54 rows is
1: _ G table: 00421258
2: string table: 00421050
3: pairs function: 00567F58
4: collectgarbage function: 005675F0
5: unpack function: 004217E8
6: assert function: 005675B0
7: print function: 00567830
8: ipairs function: 00567F28
9: type function: 004217A8
10: tonumber function: 00421768
11: tostring function: 00421788
12: table: 00420DA8
13: math table: 004210C8
14: setretriable function: 00421748
15: getretriable function: 00567710
16: pcall function: 005677F0
17: Response = nil
Row 54 cannot be accessed because this global function is not registered
Response = [string "ProtectedFunction ()"]: 1: attempt to call global 'protectedfunction' (a nil value)
This function is added to row 58 in the global environment, so the access to row 60 is normal.
Protected func
Response = nil
From the treasure Building