mods that hopefully work for a TechAge-based pack
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
--[[
|
||||
|
||||
SaferLua [safer_lua]
|
||||
====================
|
||||
|
||||
Copyright (C) 2018 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
scanner.lua:
|
||||
|
||||
]]--
|
||||
|
||||
local function trim(s)
|
||||
return (s:gsub("^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
|
||||
function safer_lua:word(ch, pttrn)
|
||||
local word = ""
|
||||
while ch:match(pttrn) do
|
||||
word = word .. ch
|
||||
self.pos = self.pos + 1
|
||||
ch = self.line:sub(self.pos, self.pos)
|
||||
end
|
||||
return word
|
||||
end
|
||||
|
||||
function safer_lua:string(pttrn)
|
||||
self.pos = self.pos + 1
|
||||
local ch = self.line:sub(self.pos, self.pos)
|
||||
while not ch:match(pttrn) and self.pos < #self.line do
|
||||
if ch == "\\" then
|
||||
self.pos = self.pos + 1
|
||||
end
|
||||
self.pos = self.pos + 1
|
||||
ch = self.line:sub(self.pos, self.pos)
|
||||
end
|
||||
self.pos = self.pos + 1
|
||||
-- result is not needed
|
||||
end
|
||||
|
||||
local function lines(str)
|
||||
local t = {}
|
||||
local function helper(line)
|
||||
table.insert(t, line)
|
||||
return ""
|
||||
end
|
||||
helper((str:gsub("(.-)\r?\n", helper)))
|
||||
return t
|
||||
end
|
||||
|
||||
function safer_lua:scanner(text)
|
||||
local lToken = {}
|
||||
for idx, line in ipairs(lines(text)) do
|
||||
self.line = line
|
||||
self.pos = 1
|
||||
self.line = trim(self.line)
|
||||
self.line = self.line:split("--", true)[1]
|
||||
table.insert(lToken, idx) -- line number
|
||||
if self.line then
|
||||
-- devide line in tokens
|
||||
while true do
|
||||
if self.pos > #self.line then break end
|
||||
local ch = self.line:sub(self.pos, self.pos)
|
||||
if ch:match("[%u%l_]") then -- identifier?
|
||||
table.insert(lToken, self:word(ch, "[%w_]"))
|
||||
elseif ch:match("[%d]") then -- number?
|
||||
table.insert(lToken, self:word(ch, "[%d%xx]"))
|
||||
elseif ch:match("'") then -- string?
|
||||
self:string("'")
|
||||
elseif ch:match('"') then -- string?
|
||||
self:string('"')
|
||||
elseif ch:match("[%s]") then -- Space?
|
||||
self.pos = self.pos + 1
|
||||
elseif ch:match("[:{}]") then -- critical tokens?
|
||||
table.insert(lToken,ch)
|
||||
self.pos = self.pos + 1
|
||||
else
|
||||
self.pos = self.pos + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return lToken
|
||||
end
|
||||
|
||||
local InvalidKeywords = {
|
||||
["while"] = true,
|
||||
["repeat"] = true,
|
||||
["until"] = true,
|
||||
["for"] = true,
|
||||
["range"] = true,
|
||||
--["function"] = true,
|
||||
["_G"] = true,
|
||||
["__load"] = true,
|
||||
["__dump"] = true,
|
||||
}
|
||||
|
||||
local InvalidChars = {
|
||||
[":"] = true,
|
||||
["{"] = true,
|
||||
["["] = true,
|
||||
["]"] = true,
|
||||
["}"] = true,
|
||||
}
|
||||
|
||||
function safer_lua:check(pos, text, label, err_clbk)
|
||||
local lToken = self:scanner(text)
|
||||
local lineno = 0
|
||||
local errno = 0
|
||||
for idx,token in ipairs(lToken) do
|
||||
if type(token) == "number" then
|
||||
lineno = token
|
||||
elseif InvalidKeywords[token] then
|
||||
if token == "for" then
|
||||
-- invalid for statement?
|
||||
if lToken[idx + 3] == "in" and lToken[idx + 5] == "next" then
|
||||
--
|
||||
elseif lToken[idx + 2] == "in" and lToken[idx + 3] == "range" then
|
||||
--
|
||||
else
|
||||
err_clbk(pos, label..":"..lineno..": Invalid use of 'for'")
|
||||
errno = errno + 1
|
||||
end
|
||||
elseif token == "range" then
|
||||
if lToken[idx - 1] ~= "in" then
|
||||
err_clbk(pos, label..":"..lineno..": Invalid use of 'range'")
|
||||
errno = errno + 1
|
||||
end
|
||||
else
|
||||
err_clbk(pos, label..":"..lineno..": Invalid keyword '"..token.."'")
|
||||
errno = errno + 1
|
||||
end
|
||||
elseif InvalidChars[token] then
|
||||
err_clbk(pos, label..":"..lineno..": Invalid character '"..token.."'")
|
||||
errno = errno + 1
|
||||
end
|
||||
end
|
||||
return errno
|
||||
end
|
||||
Reference in New Issue
Block a user