-
Notifications
You must be signed in to change notification settings - Fork 118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Luacontroller recursive table interrupt iid crash #473
Comments
That shouldn’t crash the server. Stack trace would be nice. |
|
So |
Maybe you could simply remove |
Still crashes with the fix merged, just in a different way: 2019-09-23 19:47:39: ERROR[Main]: ServerError: AsyncErr: ServerThread::run Lua: Runtime error from mod 'mesecons_luacontroller' in callback node_on_receive_fields(): minetest/bin/../mods/mesecons-mp/mesecons/util.lua:197: stack overflow 2019-09-23 19:47:39: ERROR[Main]: stack traceback: 2019-09-23 19:47:39: ERROR[Main]: minetest/bin/../mods/mesecons-mp/mesecons/util.lua:197: in function 'cmpAny' 2019-09-23 19:47:39: ERROR[Main]: minetest/bin/../mods/mesecons-mp/mesecons/util.lua:201: in function 'cmpAny' 2019-09-23 19:47:39: ERROR[Main]: minetest/bin/../mods/mesecons-mp/mesecons/util.lua:201: in function 'cmpAny' 2019-09-23 19:47:39: ERROR[Main]: minetest/bin/../mods/mesecons-mp/mesecons/util.lua:201: in function 'cmpAny' 2019-09-23 19:47:39: ERROR[Main]: minetest/bin/../mods/mesecons-mp/mesecons/util.lua:201: in function 'cmpAny' 2019-09-23 19:47:39: ERROR[Main]: minetest/bin/../mods/mesecons-mp/mesecons/util.lua:201: in function 'cmpAny' 2019-09-23 19:47:39: ERROR[Main]: minetest/bin/../mods/mesecons-mp/mesecons/util.lua:201: in function 'cmpAny' 2019-09-23 19:47:39: ERROR[Main]: minetest/bin/../mods/mesecons-mp/mesecons/util.lua:201: in function 'cmpAny' 2019-09-23 19:47:39: ERROR[Main]: minetest/bin/../mods/mesecons-mp/mesecons/util.lua:201: in function 'cmpAny' 2019-09-23 19:47:39: ERROR[Main]: minetest/bin/../mods/mesecons-mp/mesecons/util.lua:201: in function 'cmpAny' 2019-09-23 19:47:39: ERROR[Main]: minetest/bin/../mods/mesecons-mp/mesecons/util.lua:201: in function 'cmpAny' 2019-09-23 19:47:39: ERROR[Main]: ... 2019-09-23 19:47:39: ERROR[Main]: minetest/bin/../mods/mesecons-mp/mesecons/util.lua:201: in function 'cmpAny' 2019-09-23 19:47:39: ERROR[Main]: minetest/bin/../mods/mesecons-mp/mesecons/util.lua:201: in function 'cmpAny' 2019-09-23 19:47:39: ERROR[Main]: minetest/bin/../mods/mesecons-mp/mesecons/util.lua:201: in function 'cmpAny' 2019-09-23 19:47:39: ERROR[Main]: minetest/bin/../mods/mesecons-mp/mesecons/util.lua:201: in function 'cmpAny' 2019-09-23 19:47:39: ERROR[Main]: minetest/bin/../mods/mesecons-mp/mesecons/util.lua:201: in function 'cmpAny' 2019-09-23 19:47:39: ERROR[Main]: bin/../mods/mesecons-mp/mesecons/actionqueue.lua:27: in function 'add_action' 2019-09-23 19:47:39: ERROR[Main]: .../bin/../mods/mesecons-mp/mesecons_luacontroller/init.lua:298: in function 'v' 2019-09-23 19:47:39: ERROR[Main]: .../bin/../mods/mesecons-mp/mesecons_luacontroller/init.lua:621: in function 'run_inner' 2019-09-23 19:47:39: ERROR[Main]: .../bin/../mods/mesecons-mp/mesecons_luacontroller/init.lua:653: in function 'set_program' 2019-09-23 19:47:39: ERROR[Main]: .../bin/../mods/mesecons-mp/mesecons_luacontroller/init.lua:745: in function <.../bin/../mods/mesecons-mp/mesecons_luacontroller/init.lua:736> |
I think that the cmpAny function works incorrectly because it iterates only over the first table: Testing if the same table keys are available could help: function mesecon.cmpAny(t1, t2)
if type(t1) ~= type(t2) then return false end
if type(t1) ~= "table" and type(t2) ~= "table" then return t1 == t2 end
for k in pairs(t2) do
if t1[k] == nil then
return false
end
end
for i, e in pairs(t1) do
if not mesecon.cmpAny(e, t2[i]) then return false end
end
return true
end This function would still ignore metatable information and keys which are tables. To fix the crash, maybe the seen parameter can be added (untested code): function mesecon.cmpAny(t1, t2, seen, seen2)
if type(t1) ~= type(t2) then
return false
end
if type(t1) ~= "table" then
return t1 == t2
end
-- Test if t2's keys are a subset of t1's keys
for k in pairs(t2) do
if t1[k] == nil then
return false
end
end
-- Test if all values in t1 are the same as those in t2
seen = seen or {}
seen2 = seen2 or {}
for i, v in pairs(t1) do
-- Do not crash with recursive tables
if not seen[v] then
if seen2[t2[i]] then
-- t2[i] leads to a cycle but t[i] does not (yet)
return false
end
seen[v] = true
seen2[t2[i]] = true
if not mesecon.cmpAny(v, t2[i], seen, seen2) then
return false
end
elseif not seen2[t2[i]] then
-- t[i] leads to a cycle but t2[i] does not
return false
end
end
return true
end |
I just understood why serialization is not used. As iteration order is undetermined, serialization result is undetermined as well: e.g. I think we should just forbid recursive tables here. Comparing them for equality is non-trivial; e.g. are |
In theory, serialization to some normal form should be possible. In non-recursive case it’s rather straightforward, and regarding performance, will be slower by itself but may (not guaranteed, though) speed up comparisons significantly. For the recursive case, the speed difference will be greater, but the normal form itself is to be figured out yet. |
* Deprecate non-string IIDs * Restrict tabular IIDs to proper trees Fixes crash on recursive interrupt ID (#473)
Server crash POC:
After browsing the source I've found that the iid is passed to add_action without serialization (init.lua)
The text was updated successfully, but these errors were encountered: