--[[ util.lua - Utility functions for the Lua sandbox Enhanced with web development utilities ]]-- local util = {} -- ====================================================================== -- CORE UTILITY FUNCTIONS -- ====================================================================== -- Generate a random token function util.generate_token(length) return __generate_token(length or 32) end -- Deep copy of tables function util.deep_copy(obj) if type(obj) ~= 'table' then return obj end local res = {} for k, v in pairs(obj) do res[k] = util.deep_copy(v) end return res end -- Merge tables function util.merge_tables(t1, t2) if type(t1) ~= 'table' or type(t2) ~= 'table' then error("Both arguments must be tables", 2) end local result = util.deep_copy(t1) for k, v in pairs(t2) do if type(v) == 'table' and type(result[k]) == 'table' then result[k] = util.merge_tables(result[k], v) else result[k] = v end end return result end -- ====================================================================== -- HTML ENTITY FUNCTIONS -- ====================================================================== -- HTML entity mapping for common characters local html_entities = { ["&"] = "&", ["<"] = "<", [">"] = ">", ['"'] = """, ["'"] = "'", ["/"] = "/", ["`"] = "`", ["="] = "=" } -- Convert special characters to HTML entities (like htmlspecialchars) function util.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 util.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 util.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
tags function util.nl2br(str) if type(str) ~= "string" then return str end return str:gsub("\r\n", "
"):gsub("\n", "
"):gsub("\r", "
") end -- ====================================================================== -- URL FUNCTIONS -- ====================================================================== -- URL encode a string function util.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 util.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 util.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 util.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 util.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 util.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 util.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 util.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 util.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 util.sanitize_string(str) if type(str) ~= "string" then return "" end return util.html_special_chars(str) end -- Sanitize to integer function util.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 util.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 util.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 util.is_url(str) then return str end -- Try to prepend http:// if it's missing if not str:match("^https?://") and util.is_url("http://" .. str) then return "http://" .. str end return "" end -- Sanitize email function util.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 util.is_email(str) then return str end return "" end -- ====================================================================== -- SECURITY FUNCTIONS -- ====================================================================== -- Basic XSS prevention function util.xss_clean(str) if type(str) ~= "string" then return str end -- Convert problematic characters to entities local result = util.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 util.base64_encode(str) if type(str) ~= "string" then return str end return __base64_encode(str) end -- Base64 decode function util.base64_decode(str) if type(str) ~= "string" then return str end return __base64_decode(str) end return util