mirror of
https://github.com/minetest-mods/mesecons.git
synced 2025-03-23 20:40:35 +01:00
Safer digilines
This commit is contained in:
parent
f78937b351
commit
4a55e3b056
@ -269,28 +269,60 @@ local function get_interrupt(pos)
|
|||||||
return interrupt
|
return interrupt
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function safe_deep_copy_helper(msg, back_references, size_limit)
|
||||||
|
local t = type(msg)
|
||||||
|
if t == "string" then
|
||||||
|
return msg, #msg + 25
|
||||||
|
elseif t == "number" then
|
||||||
|
return msg, 8
|
||||||
|
elseif t == "boolean" then
|
||||||
|
return msg, 1
|
||||||
|
elseif t == "table" then
|
||||||
|
local bref = back_references[msg]
|
||||||
|
if bref then
|
||||||
|
return bref, 0
|
||||||
|
end
|
||||||
|
local cost = 8
|
||||||
|
local ret = {}
|
||||||
|
back_references[msg] = ret
|
||||||
|
for k, v in pairs(msg) do
|
||||||
|
local k_cost, v_cost
|
||||||
|
k, k_cost = safe_deep_copy_helper(k, back_references, size_limit)
|
||||||
|
v, v_cost = safe_deep_copy_helper(v, back_references, size_limit)
|
||||||
|
if k == nil or v == nil then
|
||||||
|
return nil, 0
|
||||||
|
end
|
||||||
|
cost = cost + k_cost + v_cost
|
||||||
|
if cost > size_limit then
|
||||||
|
return nil, 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return ret, cost
|
||||||
|
else
|
||||||
|
return nil, 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function safe_deep_copy(msg, size_limit)
|
||||||
|
local result, cost = safe_deep_copy_helper(msg, {}, size_limit)
|
||||||
|
if cost > size_limit then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
local function get_digiline_send(pos)
|
local function get_digiline_send(pos)
|
||||||
if not digiline then return end
|
if not minetest.global_exists("digilines") then return end
|
||||||
return function(channel, msg)
|
return function(channel, msg)
|
||||||
-- Make sure channel is string, number or boolean
|
-- Make sure channel is string, number or boolean
|
||||||
if (type(channel) ~= "string" and type(channel) ~= "number" and type(channel) ~= "boolean") then
|
if (type(channel) ~= "string" and type(channel) ~= "number" and type(channel) ~= "boolean") then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
local clean_msg = safe_deep_copy(msg, mesecon.setting("luacontroller_digiline_maxlen", 50000))
|
||||||
-- It is technically possible to send functions over the wire since
|
if clean_msg == nil then
|
||||||
-- the high performance impact of stripping those from the data has
|
|
||||||
-- been decided to not be worth the added realism.
|
|
||||||
-- Make sure serialized version of the data is not insanely long to
|
|
||||||
-- prevent DoS-like attacks
|
|
||||||
local msg_ser = minetest.serialize(msg)
|
|
||||||
if #msg_ser > mesecon.setting("luacontroller_digiline_maxlen", 50000) then
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
minetest.after(0, digilines.receptor_send, pos, digilines.rules.default, channel, clean_msg)
|
||||||
minetest.after(0, function()
|
|
||||||
digiline:receptor_send(pos, digiline.rules.default, channel, msg)
|
|
||||||
end)
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user