Index: trunk/phase3/includes/IP.php |
— | — | @@ -35,16 +35,16 @@ |
36 | 36 | define( 'RE_IPV6_V4_PREFIX', '0*' . RE_IPV6_GAP . '(?:ffff:)?' ); |
37 | 37 | // An IPv6 block is an IP address and a prefix (d1 to d128) |
38 | 38 | define( 'RE_IPV6_PREFIX', '(12[0-8]|1[01][0-9]|[1-9]?\d)'); |
39 | | -// An IPv6 IP is made up of 8 octets. However abbreviations like "::" can be used. |
40 | | -// This is lax! The number of colon groups is checked (1 to 7) but |
41 | | -// the number of double colons is not validated (must be 0 to 1). |
| 39 | +// An IPv6 address is made up of 8 octets. However, the "::" abbreviations can be used. |
42 | 40 | define( 'RE_IPV6_ADD', |
43 | | - '(' . |
44 | | - ':(:' . RE_IPV6_WORD . '){1,7}' . // starts with "::" |
45 | | - '|' . |
46 | | - RE_IPV6_WORD . '(:{1,2}' . RE_IPV6_WORD . '){0,6}::' . // ends with "::" |
47 | | - '|' . |
48 | | - RE_IPV6_WORD . '(:{1,2}' . RE_IPV6_WORD . '){1,7}' . // neither of the above |
| 41 | + '(' . // starts with "::" (includes the address "::") |
| 42 | + '(::|:(:' . RE_IPV6_WORD . '){1,7})' . |
| 43 | + '|' . // ends with "::" (not including the address "::") |
| 44 | + RE_IPV6_WORD . '(:' . RE_IPV6_WORD . '){0,6}::' . |
| 45 | + '|' . // has no "::" |
| 46 | + RE_IPV6_WORD . '(:' . RE_IPV6_WORD . '){7}' . |
| 47 | + '|' . // contains one "::" in the middle ("^" check always fails if no "::" found) |
| 48 | + RE_IPV6_WORD . '(:(?P<abbr>(?(abbr)|:))?' . RE_IPV6_WORD . '){1,6}(?(abbr)|^)' . |
49 | 49 | ')' |
50 | 50 | ); |
51 | 51 | define( 'RE_IPV6_BLOCK', RE_IPV6_ADD . '\/' . RE_IPV6_PREFIX ); |
— | — | @@ -72,11 +72,7 @@ |
73 | 73 | if ( !$ip ) { |
74 | 74 | return false; |
75 | 75 | } |
76 | | - if ( is_array( $ip ) ) { |
77 | | - throw new MWException( 'invalid value passed to ' . __METHOD__ ); |
78 | | - } |
79 | | - return preg_match( '/^' . IP_ADDRESS_STRING . '$/', $ip ) |
80 | | - && ( substr_count( $ip, '::' ) <= 1 ); // IPv6 IPs with 2+ "::" are ambiguous |
| 76 | + return preg_match( '/^' . IP_ADDRESS_STRING . '$/', $ip ); |
81 | 77 | } |
82 | 78 | |
83 | 79 | /** |
— | — | @@ -89,11 +85,7 @@ |
90 | 86 | if ( !$ip ) { |
91 | 87 | return false; |
92 | 88 | } |
93 | | - if ( is_array( $ip ) ) { |
94 | | - throw new MWException( 'invalid value passed to ' . __METHOD__ ); |
95 | | - } |
96 | | - return preg_match( '/^' . RE_IPV6_ADD . '(\/' . RE_IPV6_PREFIX . '|)$/', $ip ) |
97 | | - && ( substr_count( $ip, '::' ) <= 1 ); // IPv6 IPs with 2+ "::" are ambiguous |
| 89 | + return preg_match( '/^' . RE_IPV6_ADD . '(\/' . RE_IPV6_PREFIX . '|)$/', $ip ); |
98 | 90 | } |
99 | 91 | |
100 | 92 | /** |
— | — | @@ -188,7 +180,7 @@ |
189 | 181 | // If the '::' is at the beginning... |
190 | 182 | if( $abbrevPos == 0 ) { |
191 | 183 | $repeat = '0:'; |
192 | | - $extra = ''; |
| 184 | + $extra = ( $ip == '::' ) ? '0' : ''; // for the address '::' |
193 | 185 | $pad = 9; // 7+2 (due to '::') |
194 | 186 | // If the '::' is at the end... |
195 | 187 | } elseif( $abbrevPos == ( $addressEnd - 1 ) ) { |
— | — | @@ -449,7 +441,9 @@ |
450 | 442 | public static function toHex( $ip ) { |
451 | 443 | $n = self::toUnsigned( $ip ); |
452 | 444 | if ( $n !== false ) { |
453 | | - $n = self::isIPv6( $ip ) ? 'v6-' . wfBaseConvert( $n, 10, 16, 32, false ) : wfBaseConvert( $n, 10, 16, 8, false ); |
| 445 | + $n = self::isIPv6( $ip ) |
| 446 | + ? 'v6-' . wfBaseConvert( $n, 10, 16, 32, false ) |
| 447 | + : wfBaseConvert( $n, 10, 16, 8, false ); |
454 | 448 | } |
455 | 449 | return $n; |
456 | 450 | } |