From 94605bbaac7260f099e78377dd423a5627b8649f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0pa=C4=8Dek?= <petr.spacek@nic.cz> Date: Sat, 16 Mar 2019 12:26:19 +0100 Subject: [PATCH] sandbox: table_print prints function signatures instead of pointers This does not work with C functions etc. but it seems that we do not expose them directly in Lua interface for users. --- daemon/lua/sandbox.lua.in | 50 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/daemon/lua/sandbox.lua.in b/daemon/lua/sandbox.lua.in index 0d27f5477..14ada7f64 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 -- GitLab