diff --git a/daemon/lua/sandbox.lua.in b/daemon/lua/sandbox.lua.in index 0d27f5477f2abcd3cf75807dd3488ade4b482a04..14ada7f64209be4c4452460516c03d629ec1b887 100644 --- a/daemon/lua/sandbox.lua.in +++ b/daemon/lua/sandbox.lua.in @@ -354,6 +354,44 @@ function eval_cmd(line, raw) end -- Pretty printing + +local function funcsign(f) +-- thanks to AnandA777 from StackOverflow! Function funcsign is adapted version of +-- https://stackoverflow.com/questions/51095022/inspect-function-signature-in-lua-5-1 + assert(type(f) == 'function', "bad argument #1 to 'funcsign' (function expected)") + local func_args = {} + pcall(function() + local oldhook + local delay = 2 + local function hook(event, line) + delay = delay - 1 + if delay == 0 then -- call this only for the introspected function + for i = 1, math.huge do + -- stack depth 2 is the introspected function + local k, v = debug.getlocal(2, i) + if (k or '('):sub(1, 1) == '(' then + break -- internal variable, skip + else + table.insert(func_args, k) + end + end + if debug.getlocal(2, -1) then + -- vararg function + table.insert(func_args, "...") + end + debug.sethook(oldhook) + error('aborting the call to introspected function') + end + end + oldhook = debug.sethook(hook, "c") -- invoke hook() on function call + -- fake arguments, necessary to detect vararg functions + fakearg = {} + for j = 1, 64 do fakearg[#fakearg + 1] = true end + f(unpack(fakearg)) -- huh? + end) + return "(" .. table.concat(func_args, ", ") .. ")" +end + function table_print (tt, indent, done) done = done or {} indent = indent or 0 @@ -394,13 +432,21 @@ function table_print (tt, indent, done) result = result .. table_print (value, indent + 4, done) result = result .. string.rep (" ", indent) result = result .. "}\n" + elseif type (value) == "function" then + result = result .. string.format("[%s] => function %s%s\n", + tostring(key), tostring(key), funcsign(value)) else result = result .. string.format("[%s] => %s\n", tostring (key), printable(value)) end end - else - result = result .. tostring(tt) .. "\n" + else -- not a table + if type(tt) == "function" then + tt_str = string.format("function%s\n", funcsign(tt)) + else + tt_str = tostring(tt) + end + result = result .. tt_str .. "\n" end return result end