|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2009-11-09 00:09 UTC] crisp at xs4all dot nl
Description: ------------ The following valid IPv6 addresses are being marked as 'invalid': a:b:c:d:e::1.2.3.4 ::0:a:b:c:d:e:f 0:a:b:c:d:e:f:: The following invalid IPv6 addresses are being marked as 'valid': ::01.02.03.04 0:0:0:255.255.255.255 please refer to the ABNF in http://rfc-ref.org/RFC-TEXTS/3986/chapter11.html Reproduce code: --------------- function validateIPv6($IP) { return filter_var($IP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6); } substitute $IP with the IPv6 addresses mentioned above PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Oct 24 01:00:02 2025 UTC |
I checked the sourcecode for the IPv6 validation and being based on tokenization instead of using regular expressions I think I can offer some guidance. I don't know C very well, but this is how I'd do it in PHP itself: function validateIPv6($IP) { $len = strlen($IP); $octets = 8; $compressed = false; $i = 0; $c = $IP[0]; while ($i < $len) { if ($c == ':') { $i++; if ($i < $len) { $c = $IP[$i]; if ($c == ':') { if (!$compressed) { $octets--; $compressed = true; $i++; } else { return false; } } elseif ($i == 1) { return false; } } else { return false; } } if ($i < $len) { $n = 0; do { $c = $IP[$i]; if ( ($c >= '0' && $c <= '9') || ($c >= 'a' && $c <= 'f') || ($c >= 'A' && $c <= 'F') ) { $n++; $i++; } elseif ($c == ':') { if ($n < 1 || $n > 4) return false; break; } elseif ($c == '.' && validateIPv4(substr($IP, $i - $n))) { $octets--; break; } else { return false; } } while ($i < $len); $octets--; } } return ($octets == 0 || ($compressed && $octets > 0)); } offcourse validateIPv4() should be fixed as well (not allow leading zeros), and you might want to add early bail-outs like when the string doesn't have any ':' characters, but I'll leave that all up to you