Jump to content

Module:IP and Module:IP/sandbox: Difference between pages

(Difference between pages)
Page 1
Page 2
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
}
}