106 lines
2.5 KiB
Python
106 lines
2.5 KiB
Python
guardrails_code = """
|
|
-- Guardrails and safe patterns for plugin development
|
|
|
|
-- Safe string operations
|
|
function safe_concat(...)
|
|
local result = {}
|
|
for i, v in ipairs({...}) do
|
|
if v ~= nil then
|
|
table.insert(result, tostring(v))
|
|
end
|
|
end
|
|
return table.concat(result)
|
|
end
|
|
|
|
-- Safe table operations
|
|
function table_contains(tbl, value)
|
|
for _, v in ipairs(tbl) do
|
|
if v == value then return true end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function table_keys(tbl)
|
|
local keys = {}
|
|
for k, _ in pairs(tbl) do
|
|
table.insert(keys, k)
|
|
end
|
|
return keys
|
|
end
|
|
|
|
function table_values(tbl)
|
|
local values = {}
|
|
for _, v in pairs(tbl) do
|
|
table.insert(values, v)
|
|
end
|
|
return values
|
|
end
|
|
|
|
-- Safe string escaping
|
|
function escape_html(str)
|
|
if str == nil then return "" end
|
|
local s = tostring(str)
|
|
s = string.gsub(s, "&", "&")
|
|
s = string.gsub(s, "<", "<")
|
|
s = string.gsub(s, ">", ">")
|
|
s = string.gsub(s, '"', """)
|
|
s = string.gsub(s, "'", "'")
|
|
return s
|
|
end
|
|
|
|
-- Pattern validation
|
|
function is_valid_filename(name)
|
|
if name == nil or name == "" then return false end
|
|
-- Block directory traversal
|
|
if string.match(name, "%.%.") then return false end
|
|
if string.match(name, "/") or string.match(name, "\\\\") then return false end
|
|
return true
|
|
end
|
|
|
|
-- Safe error handling wrapper
|
|
function try_catch(fn, catch_fn)
|
|
local status, err = pcall(fn)
|
|
if not status and catch_fn then
|
|
catch_fn(err)
|
|
end
|
|
return status
|
|
end
|
|
|
|
-- Request validation
|
|
function validate_request(req, required_fields)
|
|
if type(req) ~= "table" then return false, "Request must be a table" end
|
|
for _, field in ipairs(required_fields) do
|
|
if req[field] == nil then
|
|
return false, "Missing required field: " .. field
|
|
end
|
|
end
|
|
return true, nil
|
|
end
|
|
|
|
-- Rate limiting helper (simple in-memory)
|
|
_rate_limits = _rate_limits or {}
|
|
function check_rate_limit(key, max_calls, window_seconds)
|
|
local now = os.time()
|
|
if _rate_limits[key] == nil then
|
|
_rate_limits[key] = {count = 1, window_start = now}
|
|
return true
|
|
end
|
|
|
|
local rl = _rate_limits[key]
|
|
if now - rl.window_start > window_seconds then
|
|
-- Reset window
|
|
rl.count = 1
|
|
rl.window_start = now
|
|
return true
|
|
end
|
|
|
|
if rl.count >= max_calls then
|
|
return false
|
|
end
|
|
|
|
rl.count = rl.count + 1
|
|
return true
|
|
end
|
|
|
|
log("Lua guardrails initialized")
|
|
""" |