mirror of
https://github.com/nmap/nmap.git
synced 2025-12-11 10:19:03 +00:00
Added strict library for libraries (and scripts). The module function is
replaced so that all NSE modules will have strict declared global checking at runtime. This should catch most developer errors early. Please see [1] for further reference into the problem. [1] http://seclists.org/nmap-dev/2009/q3/0070.html
This commit is contained in:
@@ -88,6 +88,8 @@ do -- Append the nselib directory to the Lua search path
|
||||
package.path = package.path..";"..path.."?.lua";
|
||||
end
|
||||
|
||||
(require "strict")() -- strict global checking
|
||||
|
||||
-- NSE_YIELD_VALUE
|
||||
-- This is the table C uses to yield a thread with a unique value to
|
||||
-- differentiate between yields initiated by NSE or regular coroutine yields.
|
||||
|
||||
83
nselib/strict.lua
Normal file
83
nselib/strict.lua
Normal file
@@ -0,0 +1,83 @@
|
||||
--- Strict Declared Global library.
|
||||
--
|
||||
-- Checks for undeclared global variables during runtime execution. This module
|
||||
-- places the 'strict' function in the global environment. The strict function
|
||||
-- allows a script to add runtime checking so that undeclared globals cause
|
||||
-- an error to be raised. This is useful for finding accidental use of globals
|
||||
-- when local was intended.
|
||||
-- A global variable is considered 'declared' if the script makes an assignment
|
||||
-- to the global name (even nil).
|
||||
--
|
||||
-- @class module
|
||||
-- @name strict
|
||||
-- @copyright Copyright© Same as Nmap--See http://nmap.org/book/man-legal.html
|
||||
|
||||
local error = error;
|
||||
local getfenv = getfenv;
|
||||
local lmodule = module;
|
||||
local rawset = rawset;
|
||||
local rawget = rawget;
|
||||
local setfenv = setfenv;
|
||||
local type = type;
|
||||
|
||||
local getinfo = debug.getinfo;
|
||||
|
||||
local function what ()
|
||||
local d = getinfo(3, "S");
|
||||
return d and d.what or "C";
|
||||
end
|
||||
|
||||
--- The strict function.
|
||||
--
|
||||
-- This function adds runtime checking to the global environment for use of
|
||||
-- undeclared globals. A global is 'undeclared' if not assigned in the file
|
||||
-- (script) scope previously. An error will be raised on use of an undeclared
|
||||
-- global.
|
||||
function strict ()
|
||||
local _G = getfenv(2);
|
||||
|
||||
local mt = getmetatable(_G) or setmetatable(_G, {}) and getmetatable(_G);
|
||||
local _newindex, _index = mt.__newindex, mt.__index;
|
||||
|
||||
mt.__declared = {};
|
||||
|
||||
function mt.__newindex (t, n, v)
|
||||
if type(_newindex) == "function" then
|
||||
_newindex(t, n, v); -- hook it
|
||||
end
|
||||
if not mt.__declared[n] then
|
||||
local w = what();
|
||||
if w ~= "main" and w ~= "C" then
|
||||
error("assign to undeclared variable '"..n.."'", 2);
|
||||
end
|
||||
mt.__declared[n] = true;
|
||||
end
|
||||
rawset(t, n, v);
|
||||
end
|
||||
|
||||
function mt.__index (t, n)
|
||||
if type(_index) == "function" then
|
||||
local v = _index(t, n); -- hook it
|
||||
if v ~= nil then return v end
|
||||
else
|
||||
local v = _index[n];
|
||||
if v ~= nil then return v end
|
||||
end
|
||||
if not mt.__declared[n] and what() ~= "C" then
|
||||
error("variable '"..n.."' is not declared", 2);
|
||||
end
|
||||
return rawget(t, n);
|
||||
end
|
||||
end
|
||||
|
||||
local strict = strict;
|
||||
|
||||
function module (...)
|
||||
local myenv = getfenv(1);
|
||||
lmodule(...);
|
||||
strict();
|
||||
setfenv(2, getfenv(1));
|
||||
setfenv(1, myenv);
|
||||
end
|
||||
|
||||
return strict;
|
||||
Reference in New Issue
Block a user