]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
modules: change the "indexing" syntax sugar for C modules
authorVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 18 Mar 2019 13:49:04 +0000 (14:49 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Thu, 13 Jun 2019 13:03:14 +0000 (15:03 +0200)
In particular, throw errors when used in weird ways,
instead of the usual "return nil" semantics.
That might be surprising to some lua users.

NEWS
daemon/lua/sandbox.lua.in

diff --git a/NEWS b/NEWS
index 8db7980fd8409ed77491e5bc3d48c67b3f5efff3..ab10219dc5f49d2031696b7670273d9908d32259 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ Improvements
 ------------
 - DNS-over-HTTPS: answers include `access-control-allow-origin: *` (!823)
 - support named AF_UNIX stream sockets for the http module (again)
+- lua tables for C modules are more strict by default, e.g. `nsid.foo`
+  will throw an error instead of returning `nil` (!797)
 
 Bugfixes
 --------
index 6d96b74a2c1c138665e1c0af791cf2124432865d..0b1eebd93fdbaa15a736fcfb22939c812e521b29 100644 (file)
@@ -179,7 +179,8 @@ function modules_create_table_for_c(kr_module_ud)
                return
        end
        local module = {}
-       _G[ffi.string(kr_module.name)] = module
+       local module_name = ffi.string(kr_module.name)
+       _G[module_name] = module
 
        --- Construct lua functions for properties.
        if kr_module.props ~= nil then
@@ -229,19 +230,33 @@ function modules_create_table_for_c(kr_module_ud)
 
        --- Add syntactic sugar for get() and set() properties.
        --- That also "catches" any commands like `moduleName.foo = bar`.
-       setmetatable(module, {
-               __index = function (t, k)
-                       local  v = rawget(t, k)
-                       if     v     then return v
-                       elseif rawget(t, 'get') then return t.get(k)
-                       end
-               end,
-               __newindex = function (t, k, v)
-                       local  old_v = rawget(t, k)
-                       if not old_v and rawget(t, 'set') then
-                               t.set(k..' '..v)
-                       end
+       local m_index, m_newindex
+       local get_f = rawget(module, 'get')
+       if get_f ~= nil then
+               m_index = function (_, key)
+                       return get_f(key)
+               end
+       else
+               m_index = function ()
+                       error('module ' .. module_name .. ' does not support indexing syntax sugar')
                end
+       end
+       local set_f = rawget(module, 'set')
+       if set_f ~= nil then
+               m_newindex = function (_, key, value)
+                       -- This will produce a nasty error on some non-string parameters.
+                       -- Still, we already use it with integer values, e.g. in predict module :-/
+                       return set_f(key .. ' ' .. value)
+               end
+       else
+               m_newindex = function ()
+                       error('module ' .. module_name .. ' does not support assignment syntax sugar')
+               end
+       end
+       setmetatable(module, {
+               -- note: the two functions only get called for *missing* indices
+               __index = m_index,
+               __newindex = m_newindex,
        })
 end