]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
sandbox: table_print prints function signatures instead of pointers
authorPetr Špaček <petr.spacek@nic.cz>
Sat, 16 Mar 2019 11:26:19 +0000 (12:26 +0100)
committerPetr Špaček <petr.spacek@nic.cz>
Wed, 10 Apr 2019 12:23:07 +0000 (14:23 +0200)
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

index 0d27f5477f2abcd3cf75807dd3488ade4b482a04..14ada7f64209be4c4452460516c03d629ec1b887 100644 (file)
@@ -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