Validate IP address patterns when creating ip-address redirect conditions

This commit is contained in:
Alejandro Celaya
2024-07-18 21:23:48 +02:00
parent ce2ed237c7
commit 7e2f755dfd
5 changed files with 185 additions and 20 deletions

View File

@@ -18,6 +18,11 @@ use function str_contains;
final class IpAddressUtils
{
public static function isStaticIpCidrOrWildcard(string $candidate): bool
{
return self::candidateToRange($candidate, ['0', '0', '0', '0']) !== null;
}
/**
* Checks if an IP address matches any of provided groups.
* Every group can be a static IP address (100.200.80.40), a CIDR block (192.168.10.0/24) or a wildcard pattern
@@ -40,15 +45,29 @@ final class IpAddressUtils
$ipAddressParts = explode('.', $ipAddress);
return some($groups, function (string $value) use ($ip, $ipAddressParts): bool {
$range = str_contains($value, '*')
? self::parseValueWithWildcards($value, $ipAddressParts)
: Factory::parseRangeString($value);
return $range !== null && $ip->matches($range);
return some($groups, function (string $group) use ($ip, $ipAddressParts): bool {
$range = self::candidateToRange($group, $ipAddressParts);
return $range !== null && $range->contains($ip);
});
}
/**
* Convert a static IP, CIDR block or wildcard pattern into a Range object
*
* @param string[] $ipAddressParts
*/
private static function candidateToRange(string $candidate, array $ipAddressParts): ?RangeInterface
{
return str_contains($candidate, '*')
? self::parseValueWithWildcards($candidate, $ipAddressParts)
: Factory::parseRangeString($candidate);
}
/**
* Try to generate an IP range from a wildcard pattern.
* Factory::parseRangeString can usually do this automatically, but only if wildcards are at the end. This also
* covers cases where wildcards are in between.
*/
private static function parseValueWithWildcards(string $value, array $ipAddressParts): ?RangeInterface
{
$octets = explode('.', $value);