293 lines
6.3 KiB
Lua
293 lines
6.3 KiB
Lua
--[[
|
|
util.lua - Utility functions for the Lua sandbox
|
|
]]--
|
|
|
|
-- ======================================================================
|
|
-- CORE UTILITY FUNCTIONS
|
|
-- ======================================================================
|
|
|
|
-- Generate a random token
|
|
function generate_token(length)
|
|
return __generate_token(length or 32)
|
|
end
|
|
|
|
-- ======================================================================
|
|
-- HTML ENTITY FUNCTIONS
|
|
-- ======================================================================
|
|
|
|
-- Convert special characters to HTML entities (like htmlspecialchars)
|
|
function html_special_chars(str)
|
|
if type(str) ~= "string" then
|
|
return str
|
|
end
|
|
|
|
return __html_special_chars(str)
|
|
end
|
|
|
|
-- Convert all applicable characters to HTML entities (like htmlentities)
|
|
function html_entities(str)
|
|
if type(str) ~= "string" then
|
|
return str
|
|
end
|
|
|
|
return __html_entities(str)
|
|
end
|
|
|
|
-- Convert HTML entities back to characters (simple version)
|
|
function html_entity_decode(str)
|
|
if type(str) ~= "string" then
|
|
return str
|
|
end
|
|
|
|
str = str:gsub("<", "<")
|
|
str = str:gsub(">", ">")
|
|
str = str:gsub(""", '"')
|
|
str = str:gsub("'", "'")
|
|
str = str:gsub("&", "&")
|
|
|
|
return str
|
|
end
|
|
|
|
-- Convert newlines to <br> tags
|
|
function nl2br(str)
|
|
if type(str) ~= "string" then
|
|
return str
|
|
end
|
|
|
|
return str:gsub("\r\n", "<br>"):gsub("\n", "<br>"):gsub("\r", "<br>")
|
|
end
|
|
|
|
-- ======================================================================
|
|
-- URL FUNCTIONS
|
|
-- ======================================================================
|
|
|
|
-- URL encode a string
|
|
function url_encode(str)
|
|
if type(str) ~= "string" then
|
|
return str
|
|
end
|
|
|
|
str = str:gsub("\n", "\r\n")
|
|
str = str:gsub("([^%w %-%_%.%~])", function(c)
|
|
return string.format("%%%02X", string.byte(c))
|
|
end)
|
|
str = str:gsub(" ", "+")
|
|
return str
|
|
end
|
|
|
|
-- URL decode a string
|
|
function url_decode(str)
|
|
if type(str) ~= "string" then
|
|
return str
|
|
end
|
|
|
|
str = str:gsub("+", " ")
|
|
str = str:gsub("%%(%x%x)", function(h)
|
|
return string.char(tonumber(h, 16))
|
|
end)
|
|
return str
|
|
end
|
|
|
|
-- ======================================================================
|
|
-- VALIDATION FUNCTIONS
|
|
-- ======================================================================
|
|
|
|
-- Email validation
|
|
function is_email(str)
|
|
if type(str) ~= "string" then
|
|
return false
|
|
end
|
|
|
|
-- Simple email validation pattern
|
|
local pattern = "^[%w%.%%%+%-]+@[%w%.%%%+%-]+%.%w%w%w?%w?$"
|
|
return str:match(pattern) ~= nil
|
|
end
|
|
|
|
-- URL validation
|
|
function is_url(str)
|
|
if type(str) ~= "string" then
|
|
return false
|
|
end
|
|
|
|
-- Simple URL validation
|
|
local pattern = "^https?://[%w-_%.%?%.:/%+=&%%]+$"
|
|
return str:match(pattern) ~= nil
|
|
end
|
|
|
|
-- IP address validation (IPv4)
|
|
function is_ipv4(str)
|
|
if type(str) ~= "string" then
|
|
return false
|
|
end
|
|
|
|
local pattern = "^(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)$"
|
|
local a, b, c, d = str:match(pattern)
|
|
|
|
if not (a and b and c and d) then
|
|
return false
|
|
end
|
|
|
|
a, b, c, d = tonumber(a), tonumber(b), tonumber(c), tonumber(d)
|
|
return a <= 255 and b <= 255 and c <= 255 and d <= 255
|
|
end
|
|
|
|
-- Integer validation
|
|
function is_int(str)
|
|
if type(str) == "number" then
|
|
return math.floor(str) == str
|
|
elseif type(str) ~= "string" then
|
|
return false
|
|
end
|
|
|
|
return str:match("^-?%d+$") ~= nil
|
|
end
|
|
|
|
-- Float validation
|
|
function is_float(str)
|
|
if type(str) == "number" then
|
|
return true
|
|
elseif type(str) ~= "string" then
|
|
return false
|
|
end
|
|
|
|
return str:match("^-?%d+%.?%d*$") ~= nil
|
|
end
|
|
|
|
-- Boolean validation
|
|
function is_bool(value)
|
|
if type(value) == "boolean" then
|
|
return true
|
|
elseif type(value) ~= "string" and type(value) ~= "number" then
|
|
return false
|
|
end
|
|
|
|
local v = type(value) == "string" and value:lower() or value
|
|
return v == "1" or v == "true" or v == "on" or v == "yes" or
|
|
v == "0" or v == "false" or v == "off" or v == "no" or
|
|
v == 1 or v == 0
|
|
end
|
|
|
|
-- Convert to boolean
|
|
function to_bool(value)
|
|
if type(value) == "boolean" then
|
|
return value
|
|
elseif type(value) ~= "string" and type(value) ~= "number" then
|
|
return false
|
|
end
|
|
|
|
local v = type(value) == "string" and value:lower() or value
|
|
return v == "1" or v == "true" or v == "on" or v == "yes" or v == 1
|
|
end
|
|
|
|
-- Sanitize string (simple version)
|
|
function sanitize_string(str)
|
|
if type(str) ~= "string" then
|
|
return ""
|
|
end
|
|
|
|
return html_special_chars(str)
|
|
end
|
|
|
|
-- Sanitize to integer
|
|
function sanitize_int(value)
|
|
if type(value) ~= "string" and type(value) ~= "number" then
|
|
return 0
|
|
end
|
|
|
|
value = tostring(value)
|
|
local result = value:match("^-?%d+")
|
|
return result and tonumber(result) or 0
|
|
end
|
|
|
|
-- Sanitize to float
|
|
function sanitize_float(value)
|
|
if type(value) ~= "string" and type(value) ~= "number" then
|
|
return 0
|
|
end
|
|
|
|
value = tostring(value)
|
|
local result = value:match("^-?%d+%.?%d*")
|
|
return result and tonumber(result) or 0
|
|
end
|
|
|
|
-- Sanitize URL
|
|
function sanitize_url(str)
|
|
if type(str) ~= "string" then
|
|
return ""
|
|
end
|
|
|
|
-- Basic sanitization by removing control characters
|
|
str = str:gsub("[\000-\031]", "")
|
|
|
|
-- Make sure it's a valid URL
|
|
if is_url(str) then
|
|
return str
|
|
end
|
|
|
|
-- Try to prepend http:// if it's missing
|
|
if not str:match("^https?://") and is_url("http://" .. str) then
|
|
return "http://" .. str
|
|
end
|
|
|
|
return ""
|
|
end
|
|
|
|
-- Sanitize email
|
|
function sanitize_email(str)
|
|
if type(str) ~= "string" then
|
|
return ""
|
|
end
|
|
|
|
-- Remove all characters except common email characters
|
|
str = str:gsub("[^%a%d%!%#%$%%%&%'%*%+%-%/%=%?%^%_%`%{%|%}%~%@%.%[%]]", "")
|
|
|
|
-- Return only if it's a valid email
|
|
if is_email(str) then
|
|
return str
|
|
end
|
|
|
|
return ""
|
|
end
|
|
|
|
-- ======================================================================
|
|
-- SECURITY FUNCTIONS
|
|
-- ======================================================================
|
|
|
|
-- Basic XSS prevention
|
|
function xss_clean(str)
|
|
if type(str) ~= "string" then
|
|
return str
|
|
end
|
|
|
|
-- Convert problematic characters to entities
|
|
local result = html_special_chars(str)
|
|
|
|
-- Remove JavaScript event handlers
|
|
result = result:gsub("on%w+%s*=", "")
|
|
|
|
-- Remove JavaScript protocol
|
|
result = result:gsub("javascript:", "")
|
|
|
|
-- Remove CSS expression
|
|
result = result:gsub("expression%s*%(", "")
|
|
|
|
return result
|
|
end
|
|
|
|
-- Base64 encode
|
|
function base64_encode(str)
|
|
if type(str) ~= "string" then
|
|
return str
|
|
end
|
|
|
|
return __base64_encode(str)
|
|
end
|
|
|
|
-- Base64 decode
|
|
function base64_decode(str)
|
|
if type(str) ~= "string" then
|
|
return str
|
|
end
|
|
|
|
return __base64_decode(str)
|
|
end |