Skip to content

Commit 8ea71a9

Browse files
committed
Fix bug where functions in Luacontroller EEPROM crashes the server (fixes #107).
1 parent 367a414 commit 8ea71a9

File tree

1 file changed

+27
-6
lines changed

1 file changed

+27
-6
lines changed

mesecons_luacontroller/init.lua

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,29 @@ local code_prohibited = function(code)
135135
end
136136
end
137137

138-
local safeprint = function(param)
138+
local safe_print = function(param)
139139
print(dump(param))
140140
end
141141

142+
deep_copy = function(original) --deep copy that removes functions
143+
if type(original) == 'table' then --nested table
144+
local copy = {}
145+
for key, value in next, original, nil do
146+
copy[deep_copy(key)] = deep_copy(value)
147+
end
148+
setmetatable(copy, deep_copy(getmetatable(original)))
149+
return copy
150+
elseif type(original) == 'function' then --ignore functions
151+
return nil
152+
else --by-value type
153+
return original
154+
end
155+
end
156+
157+
local safe_serialize = function(value)
158+
return minetest.serialize(deep_copy(value))
159+
end
160+
142161
local interrupt = function(params)
143162
lc_update(params.pos, {type="interrupt", iid = params.iid})
144163
end
@@ -150,15 +169,16 @@ local getinterrupt = function(pos)
150169
local meta = minetest.env:get_meta(pos)
151170
local interrupts = minetest.deserialize(meta:get_string("lc_interrupts")) or {}
152171
local found = false
172+
local search = safe_serialize(iid)
153173
for _, i in ipairs(interrupts) do
154-
if minetest.serialize(i) == minetest.serialize(iid) then
174+
if safe_serialize(i) == search then
155175
found = true
156176
break
157177
end
158178
end
159179
if not found then
160180
table.insert(interrupts, iid)
161-
meta:set_string("lc_interrupts", minetest.serialize(interrupts))
181+
meta:set_string("lc_interrupts", safe_serialize(interrupts))
162182
end
163183
minetest.after(time, interrupt, {pos=pos, iid = iid})
164184
end
@@ -181,7 +201,7 @@ local create_environment = function(pos, mem, event)
181201
local rports = get_real_portstates(pos)
182202

183203
return {
184-
print = safeprint,
204+
print = safe_print,
185205
pin = merge_portstates(vports, rports),
186206
port = vports,
187207
interrupt = getinterrupt(pos),
@@ -272,15 +292,16 @@ local load_memory = function(meta)
272292
end
273293

274294
local save_memory = function(meta, mem)
275-
meta:set_string("lc_memory", minetest.serialize(mem))
295+
meta:set_string("lc_memory", safe_serialize(mem))
276296
end
277297

278298
local interrupt_allow = function (meta, event)
279299
if event.type ~= "interrupt" then return true end
280300

281301
local interrupts = minetest.deserialize(meta:get_string("lc_interrupts")) or {}
302+
local search = safe_serialize(event.iid)
282303
for _, i in ipairs(interrupts) do
283-
if minetest.serialize(i) == minetest.serialize(event.iid) then
304+
if safe_serialize(i) == search then
284305
return true
285306
end
286307
end

0 commit comments

Comments
 (0)