lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


David Given wrote:
> function create_secure_table()
>   local data = {}
>   local mt = {
>     __index = function(t, k) return data[k] end,
>     __newindex = function(t, k, v) data[k] = v end
>   }
>   local t = {
>     newkey = function() return {} end
>   }
>   setmetatable(t, mt)
>   return t
> end

That's an elegant solution, demonstrating Lua's lexical scoping.

Note that 't[4] = 5' is allowed, but the 4 is still hidden even though
it is not unique. There's no way to know that it is a key without the
debug library. Iteration over the keys is still not possible, so this
would probably be enough.

But to prohibit normal indexing (that is, to prohibit the use of
anything except hidden, unique keys), you could add an upvalue table to
hold the keys and then only allow indexing based on those keys:

function create_protected_table()
  local key = {}
  local data = {}
  local mt = {
    __index = function(t, k) return data[k] end,
    __newindex =
       function(t, k, v)
          if not key[k] then
             error('use t:newkey() to create a secure key')
          end
          data[k] = v
       end
  }
  local t = {
     newkey =
        function(self, v)
           local k = {}
           key[k] = true
           return k
        end
  }
  setmetatable(t, mt)
  return t
end

p = create_protected_table()
k = p:newkey()
print(p[k])
p[k] = 9
print(p[k])
p[3] = 5   -- Allowed in David's code; key is hidden.

-- Output:
-- nil
-- 9
-- stdin:9: use t:newkey() to create a secure key
-- stack traceback:
--         [C]: in function 'error'
--         stdin:9: in function <stdin:7>
--         stdin:1: in main chunk
--         [C]: ?

Doug

-- 
Innovative Concepts, Inc. www.innocon.com 703-893-2007 x220