Module:IP and Module:IP/sandbox: Difference between pages
Appearance
(Difference between pages)
Content deleted Content added
use require('strict') instead of require('Module:No globals') |
Add static Util class (Util.removeDirMarkers is adapted from Module:IPAddress (2023-02-14T03:16:49)) |
||
Line 1,013: | Line 1,013: | ||
return self |
return self |
||
end |
end |
||
end |
|||
-------------------------------------------------------------------------------- |
|||
-- Util class (static) |
|||
-- Holds utility functions. |
|||
-------------------------------------------------------------------------------- |
|||
local Util = {} |
|||
function Util.removeDirMarkers(str) |
|||
-- Remove any of following directional markers |
|||
-- LRM : LEFT-TO-RIGHT MARK (U+200E) : hex e2 80 8e = 226 128 142 |
|||
-- LRE : LEFT-TO-RIGHT EMBEDDING (U+202A) : hex e2 80 aa = 226 128 170 |
|||
-- PDF : POP DIRECTIONAL FORMATTING (U+202C) : hex e2 80 ac = 226 128 172 |
|||
-- This is required for MediaWiki:Blockedtext message. |
|||
return string.gsub(str, '\226\128[\142\170\172]', '') |
|||
end |
|||
local function correctCidr(cidrStr) |
|||
-- Correct a well-formatted but invalid CIDR string to a valid one (e.g. 255.255.255.1/24 -> 255.255.255.0/24). |
|||
-- Return a Subnet object only if correction takes place. |
|||
local isCidr, cidr = pcall(Subnet.new, cidrStr) |
|||
local i, _ = string.find(cidrStr, '/%d+$'); |
|||
if not isCidr and i ~= nil and i > 1 then |
|||
local bitLen = tonumber(cidrStr:sub(i + 1)) |
|||
local root = cidrStr:sub(1, i - 1) |
|||
local isIp, ip = pcall(IPAddress.new, root) |
|||
if isIp then |
|||
local isValidSubnet = ip:isIPv4() and 0 <= bitLen and bitLen <= 32 or ip:isIPv6() and 0 <= bitLen and bitLen <= 128 |
|||
if isValidSubnet then |
|||
return ip:getSubnet(bitLen) |
|||
end |
|||
end |
|||
end |
|||
return nil |
|||
end |
|||
local function isSpecifiedProtocol(obj, protocol) |
|||
-- Check if a given IPAddress/Subnet object is an instance of IPv4, IPv6, or either, and return a boolean value. |
|||
if protocol == 'v4' then |
|||
return obj:isIPv4() |
|||
elseif protocol == 'v6' then |
|||
return obj:isIPv6() |
|||
else |
|||
return obj:isIPv4() or obj:isIPv6() |
|||
end |
|||
end |
|||
local function verifyIP(str, allowCidr, cidrOnly, protocol) |
|||
-- Return 3 values: boolean, string, string/nil. |
|||
-- v[1] is the result of whether the input string is an IP address or CIDR of the specified protocol (IPv4, IPv6, or either). |
|||
-- v[2] is the input string. |
|||
-- v[3] is a corrected CIDR string only if allowCidr or cidrOnly is true AND v[1] is true AND the input string is in a possible |
|||
-- CIDR format but doesn't actually work as a CIDR and hence is corrected to a valid one (e.g. 1.2.3.4/24 -> 1.2.3.0/24). |
|||
str = Util.removeDirMarkers(str) |
|||
if cidrOnly == true then allowCidr = true end -- Ignores the value of allowCidr if cidrOnly is true |
|||
if allowCidr then |
|||
local corCidr = correctCidr(str) |
|||
local corrected = corCidr ~= nil |
|||
local isCidr, cidr |
|||
if corrected then |
|||
isCidr, cidr = true, corCidr |
|||
else |
|||
isCidr, cidr = pcall(Subnet.new, str) |
|||
end |
|||
if isCidr then -- The input (or corrected) string represents a valid CIDR |
|||
isCidr = isSpecifiedProtocol(cidr, protocol) |
|||
return isCidr, str, (function() if isCidr and corrected then return cidr:getCIDR() end end)() |
|||
elseif cidrOnly then -- Invalid as a CIDR |
|||
return false, str, nil |
|||
end |
|||
end |
|||
local isIp, ip = pcall(IPAddress.new, str) |
|||
if isIp then |
|||
isIp = isSpecifiedProtocol(ip, protocol) |
|||
end |
|||
return isIp, str, nil |
|||
end |
|||
function Util.isIPAddress(str, allowCidr, cidrOnly) |
|||
return verifyIP(str, allowCidr, cidrOnly, nil) |
|||
end |
|||
function Util.isIPv4Address(str, allowCidr, cidrOnly) |
|||
return verifyIP(str, allowCidr, cidrOnly, 'v4') |
|||
end |
|||
function Util.isIPv6Address(str, allowCidr, cidrOnly) |
|||
return verifyIP(str, allowCidr, cidrOnly, 'v6') |
|||
end |
end |
||
Line 1,020: | Line 1,109: | ||
IPv4Collection = IPv4Collection, |
IPv4Collection = IPv4Collection, |
||
IPv6Collection = IPv6Collection, |
IPv6Collection = IPv6Collection, |
||
Util = Util |
|||
} |
} |