summaryrefslogtreecommitdiff
path: root/example/simple-example.lua
blob: a7ca3d47bf3c0b5ec8696826bdd2c25934a74fb9 (plain)
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" }))