X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FIP.php;h=db712c3bcd5087207145c4666a42ac089931e07c;hb=0495f90ebb83c0295f67b9da410ddf3b0534ca38;hp=d9906c5343412264aab510392831980b8404c30a;hpb=5fef2333d43faed0571878e848d6c40ade2c9810;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/IP.php b/includes/IP.php index d9906c5343..db712c3bcd 100644 --- a/includes/IP.php +++ b/includes/IP.php @@ -22,7 +22,12 @@ define( 'RE_IPV6_PREFIX', '(12[0-8]|1[01][0-9]|[1-9]?\d)'); define( 'RE_IPV6_ADD', '(:(:' . RE_IPV6_WORD . '){1,7}|' . RE_IPV6_WORD . '(:{1,2}' . RE_IPV6_WORD . '|::$){1,7})' ); define( 'RE_IPV6_BLOCK', RE_IPV6_ADD . '\/' . RE_IPV6_PREFIX ); // This might be useful for regexps used elsewhere, matches any IPv6 or IPv6 address or network -define( 'IP_ADDRESS_STRING', RE_IP_ADD . '(\/' . RE_IP_PREFIX . '|)|' . RE_IPV6_ADD . '(\/' . RE_IPV6_PREFIX . '|)'); +define( 'IP_ADDRESS_STRING', + '(?:' . + RE_IP_ADD . '(\/' . RE_IP_PREFIX . '|)' . + '|' . + RE_IPV6_ADD . '(\/' . RE_IPV6_PREFIX . '|)' . + ')' ); /** * A collection of public static functions to play with IP address @@ -37,12 +42,18 @@ class IP { */ public static function isIPAddress( $ip ) { if ( !$ip ) return false; + if ( is_array( $ip ) ) { + throw new MWException( "invalid value passed to " . __METHOD__ ); + } // IPv6 IPs with two "::" strings are ambiguous and thus invalid return preg_match( '/^' . IP_ADDRESS_STRING . '$/', $ip) && ( substr_count($ip, '::') < 2 ); } public static function isIPv6( $ip ) { if ( !$ip ) return false; + if( is_array( $ip ) ) { + throw new MWException( "invalid value passed to " . __METHOD__ ); + } // IPv6 IPs with two "::" strings are ambiguous and thus invalid return preg_match( '/^' . RE_IPV6_ADD . '(\/' . RE_IPV6_PREFIX . '|)$/', $ip) && ( substr_count($ip, '::') < 2); } @@ -103,13 +114,14 @@ class IP { * @return string */ public static function sanitizeIP( $ip ) { - if ( !$ip ) return null; + $ip = trim( $ip ); + if ( $ip === '' ) return null; // Trim and return IPv4 addresses - if ( self::isIPv4($ip) ) return trim($ip); + if ( self::isIPv4($ip) ) return $ip; // Only IPv6 addresses can be expanded if ( !self::isIPv6($ip) ) return $ip; // Remove any whitespaces, convert to upper case - $ip = strtoupper( trim($ip) ); + $ip = strtoupper( $ip ); // Expand zero abbreviations if ( strpos( $ip, '::' ) !== false ) { $ip = str_replace('::', str_repeat(':0', 8 - substr_count($ip, ':')) . ':', $ip); @@ -197,7 +209,7 @@ class IP { # Convert to hex $end = wfBaseConvert( $end, 2, 16, 32, false ); # see toHex() comment - $start = "ipv6-$start"; $end = "ipv6-$end"; + $start = "v6-$start"; $end = "v6-$end"; } } elseif ( strpos( $range, '-' ) !== false ) { # Explicit range @@ -210,7 +222,7 @@ class IP { $end = wfBaseConvert( $end, 10, 16, 32, false ); } # see toHex() comment - $start = "ipv6-$start"; $end = "ipv6-$end"; + $start = "v6-$start"; $end = "v6-$end"; } else { # Single IP $start = $end = self::toHex( $range ); @@ -280,7 +292,7 @@ class IP { * Split out an IP block as an array of 4 bytes and a mask, * return false if it can't be determined * - * @parameter $ip string A quad dotted/octet IP address + * @param $ip string A quad dotted/octet IP address * @return array */ public static function toArray( $ipblock ) { @@ -394,7 +406,7 @@ class IP { * * 2001:0db8:85a3::7344/96 CIDR * 2001:0db8:85a3::7344 - 2001:0db8:85a3::7344 Explicit range - * 2001:0db8:85a3::7344/96 Single IP + * 2001:0db8:85a3::7344 Single IP * @return array(string, int) */ public static function parseRange( $range ) { @@ -456,22 +468,29 @@ class IP { * @return valid dotted quad IPv4 address or null */ public static function canonicalize( $addr ) { - if ( self::isValid( $addr ) ) - return $addr; + if ( self::isValid( $addr ) ) + return $addr; - // IPv6 loopback address - $m = array(); - if ( preg_match( '/^0*' . RE_IPV6_GAP . '1$/', $addr, $m ) ) - return '127.0.0.1'; + // Annoying IPv6 representations like ::ffff:1.2.3.4 + if ( strpos($addr,':') !==false && strpos($addr,'.') !==false ) { + $addr = str_replace( '.', ':', $addr ); + if( IP::isIPv6( $addr ) ) + return $addr; + } + + // IPv6 loopback address + $m = array(); + if ( preg_match( '/^0*' . RE_IPV6_GAP . '1$/', $addr, $m ) ) + return '127.0.0.1'; - // IPv4-mapped and IPv4-compatible IPv6 addresses - if ( preg_match( '/^' . RE_IPV6_V4_PREFIX . '(' . RE_IP_ADD . ')$/i', $addr, $m ) ) - return $m[1]; - if ( preg_match( '/^' . RE_IPV6_V4_PREFIX . RE_IPV6_WORD . ':' . RE_IPV6_WORD . '$/i', $addr, $m ) ) - return long2ip( ( hexdec( $m[1] ) << 16 ) + hexdec( $m[2] ) ); + // IPv4-mapped and IPv4-compatible IPv6 addresses + if ( preg_match( '/^' . RE_IPV6_V4_PREFIX . '(' . RE_IP_ADD . ')$/i', $addr, $m ) ) + return $m[1]; + if ( preg_match( '/^' . RE_IPV6_V4_PREFIX . RE_IPV6_WORD . ':' . RE_IPV6_WORD . '$/i', $addr, $m ) ) + return long2ip( ( hexdec( $m[1] ) << 16 ) + hexdec( $m[2] ) ); - return null; // give up + return null; // give up } } -?> +