1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
-- example/simple-example.lua
--
-- Sandbox (for) Untrusted Procedure Partitioning (in) Lua Engine
--
-- Simple example
--
-- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org>
--
-- For licence terms, see COPYING
--
supple = require'supple'
-- Code string to run in the untrusted environment
subcode = [[
local t = ...
local tot = 0
for i = 1, #t do
tot = tot + t[i]()
end
t.tot = tot
return tot, -t
]]
-- Generate a function to return 'n'
local function give_n(n)
return function() return n end
end
-- A useful table for the test
local tab = {
give_n(4),
give_n(8),
give_n(12),
}
-- A metatable which defines -tab to equal 'JEFF'
local mt = {
__unm = function () return "JEFF" end
}
setmetatable(tab, mt)
local function lprint(...)
local foo = {n=select("#",...),...}
if foo[1] then
print "Function ran OK:"
else
print "Error encountered:"
end
for i = 2, foo.n do
if type(foo[i]) == "table" then
print("{")
for k, v in pairs(foo[i]) do
print("",k,v)
end
print("}")
else
print(foo[i])
end
end
print()
end
-- Finally, run the subcode
lprint(supple.host.run(subcode, "@test-code", tab))
assert(tab.tot == 24)
-- Now run a supple command which we expect to error out.
lprint(supple.host.run("unknown()", "@test-code"))
-- And now, one where we pass an error from host to sandbox and back
lprint(supple.host.run("local f = ... f()", "@test-code", function() unknown() end))
-- And now, one where we pass an error from sandbox to host to sandbox and back
lprint(supple.host.run("local f = ... f(function() unknown() end)", "@test-code", function(ff) ff() end))
-- Next , a reasonable traceback via named functions on each end...
local errsrc = [[
function raises()
does_not_exist()
end
function passes()
raises()
end
function chains(f)
f(passes)
end
local callme = ...
callme(chains)
]]
function loopback(f)
f(loopback)
end
lprint(supple.host.run(errsrc, "@error-code", loopback))
-- Now we try the sandboxing limits
local long_run = [[
local s = ""
for i = 1, 10000 do
s = s .. "FISHFISHFISHFISHFISH"
end
return #s
]]
supple.host.set_limits { count = 100 }
lprint(supple.host.run(long_run, "@long-code"))
supple.host.set_limits { memory = 1000 }
lprint(supple.host.run(long_run, "@big-code"))
-- next we demonstrate that ipairs works on proxied tables
local summing = [[
local t = ...
local tot = 0
for i, v in ipairs(t) do
tot = tot + v
end
return tot
]]
lprint(supple.host.run(summing, "@summing", { 10, 14, 3 }))
-- next we demonstrate that next works on proxied tables
local isempty = [[
local t = ...
return next(t) == nil
]]
lprint(supple.host.run(isempty, "@isempty", {}))
lprint(supple.host.run(isempty, "@isempty", {"bar"}))
-- And now that pairs works on proxied tables
local keys = [[
local t = ...
local ret = {}
for k, v in pairs(t) do
ret[#ret+1] = k
end
ret.ret = ret
return ret
]]
lprint(supple.host.run(keys, "@keys", { foo="bar", baz="meta" }))
|