From 42d221745703df7b1ed6797190870497edb01c34 Mon Sep 17 00:00:00 2001 From: Tobias Ulmer Date: Thu, 6 Feb 2014 18:04:37 +0100 Subject: [PATCH] Make dofile2() more strict, improving config file error detection The capability to disallow global variables and reading undefined variables in configs existed for a long time but was not enabled for most files... Implements bz#127 Signed-off-by: Tobias Ulmer --- generic/e2lib.lua | 39 ++++++++++++++++++++------------------- generic/e2option.lua | 2 +- local/e2tool.lua | 19 ++++++++++--------- local/licence.lua | 2 +- 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/generic/e2lib.lua b/generic/e2lib.lua index 49742a5..2112cff 100644 --- a/generic/e2lib.lua +++ b/generic/e2lib.lua @@ -907,27 +907,26 @@ function e2lib.get_global_config() end -- use ipairs to keep the list entries ordered for _,path in ipairs(cf_path) do - local c = {} - c.config = function(x) - c.data = x - end + local data = nil + e2lib.logf(4, "reading global config file: %s", path) local rc = e2lib.exists(path) if rc then e2lib.logf(3, "using global config file: %s", path) - rc, re = e2lib.dofile2(path, c, true) + rc, re = e2lib.dofile2(path, + { config = function(x) data = x end }) if not rc then return false, re end - if not c.data then + if not data then return false, err.new("invalid configuration") end - rc, re = verify_global_config(c.data) + rc, re = verify_global_config(data) if not rc then return false, re end - get_global_config_cache = strict.lock(c.data) + get_global_config_cache = strict.lock(data) return get_global_config_cache else e2lib.logf(4, "global config file does not exist: %s", path) @@ -957,20 +956,18 @@ function e2lib.read_extension_config(root) e2lib.logf(3, "reading extension file: %s", extension_config) - local c = {} - c.extensions = function(x) - c.data = x - end - rc, re = e2lib.dofile2(extension_config, c, true) + local data = nil + rc, re = e2lib.dofile2(extension_config, + { extensions = function(x) data = x end }) if not rc then return false, e:cat(re) end - if not c.data then + if not data then return false, e:append("invalid extension configuration") end - return c.data + return data end --- Successively returns the file names in the directory. @@ -1469,17 +1466,21 @@ end --- Executes Lua code loaded from path. --@param path Filename to load lua code from (string). --@param gtable Environment (table) that is used instead of the global _G. ---@param allownewdefs Boolean indicating whether new variables may be defined --- and undefined ones read. +-- If gtable has no metatable, the default is to reject +-- __index and __newindex access. --@return True on success, false on error. --@return Error object on failure. -function e2lib.dofile2(path, gtable, allownewdefs) +function e2lib.dofile2(path, gtable) local e = err.new("error loading config file: %s", path) local chunk, msg = loadfile(path) if not chunk then return false, e:cat(msg) end + --for k,v in pairs(gtable) do + -- e2lib.logf(1, "[%s] = %s", tostring(k), tostring(v)) + --end + local function checkread(t, k) local x = rawget(t, k) if x then @@ -1496,7 +1497,7 @@ function e2lib.dofile2(path, gtable, allownewdefs) path, tostring(k), tostring(v)), 0) end - if not allownewdefs then + if not getmetatable(gtable) then setmetatable(gtable, { __newindex = checkwrite, __index = checkread }) end diff --git a/generic/e2option.lua b/generic/e2option.lua index 220ef9c..4725808 100644 --- a/generic/e2option.lua +++ b/generic/e2option.lua @@ -238,7 +238,7 @@ local function userdefaultoptions(opts) end local e2rc = {} - local rc, e = e2lib.dofile2(file, { e2rc = function(t) e2rc = t end }, false) + local rc, e = e2lib.dofile2(file, { e2rc = function(t) e2rc = t end }) if not rc then return false, e end diff --git a/local/e2tool.lua b/local/e2tool.lua index f5ac6dd..ebbd40b 100644 --- a/local/e2tool.lua +++ b/local/e2tool.lua @@ -181,7 +181,7 @@ local function load_user_config(info, path, dest, index, var) dest[index] = table end - local rc, re = e2lib.dofile2(path, { [var] = func, env = info.env, string=string }, false) + local rc, re = e2lib.dofile2(path, { [var] = func, env = info.env, string=string }) if not rc then return false, e:cat(re) end @@ -252,11 +252,11 @@ local function load_user_config2(info, path, types) local g = {} -- compose the environment for the config file g.env = info.env -- env g.string = string -- string - for _,type in ipairs(types) do - g[type] = f[type] -- and some config functions + for _,typ in ipairs(types) do + g[typ] = f[typ] -- and some config functions end - rc, re = e2lib.dofile2(path, g, true) + rc, re = e2lib.dofile2(path, g) if not rc then return false, e:cat(re) end @@ -599,11 +599,12 @@ local function load_env_config(info, file) table.insert(info.env_files, file) local path = e2lib.join(info.root, file) - local g = {} -- compose the environment for the config file - g.e2env = info.env -- env as built up so far - g.string = string -- string - g.env = mergeenv - rc, re = e2lib.dofile2(path, g, true) + local g = { + e2env = info.env, + string = string, + env = mergeenv, + } + rc, re = e2lib.dofile2(path, g) if not rc then return false, e:cat(re) end diff --git a/local/licence.lua b/local/licence.lua index 7cebaee..c3faabc 100644 --- a/local/licence.lua +++ b/local/licence.lua @@ -166,7 +166,7 @@ function licence.load_licence_config(info) end rc, re = e2lib.dofile2(path, - { e2licence = assign, env = info.env, string = string }, false) + { e2licence = assign, env = info.env, string = string }) if not rc then return false, re end -- 2.39.5