Index: trunk/phase3/includes/Title.php |
— | — | @@ -1916,7 +1916,9 @@ |
1917 | 1917 | $this->mNamespace != NS_MAIN ) { |
1918 | 1918 | return false; |
1919 | 1919 | } |
1920 | | - |
| 1920 | + // Allow IPv6 to start with '::' by expanding it. |
| 1921 | + // This trims all input, but that happens anyway. |
| 1922 | + $dbkey = IP::sanitizeIP( $dbkey ); |
1921 | 1923 | // Any remaining initial :s are illegal. |
1922 | 1924 | if ( $dbkey !== '' && ':' == $dbkey{0} ) { |
1923 | 1925 | return false; |
Index: trunk/phase3/includes/IP.php |
— | — | @@ -468,21 +468,28 @@ |
469 | 469 | * @return valid dotted quad IPv4 address or null |
470 | 470 | */ |
471 | 471 | public static function canonicalize( $addr ) { |
472 | | - if ( self::isValid( $addr ) ) |
473 | | - return $addr; |
| 472 | + if ( self::isValid( $addr ) ) |
| 473 | + return $addr; |
474 | 474 | |
475 | | - // IPv6 loopback address |
476 | | - $m = array(); |
477 | | - if ( preg_match( '/^0*' . RE_IPV6_GAP . '1$/', $addr, $m ) ) |
478 | | - return '127.0.0.1'; |
| 475 | + // Annoying IPv6 representations like ::ffff:1.2.3.4 |
| 476 | + if ( strpos($addr,':') !==false && strpos($addr,'.') !==false ) { |
| 477 | + $addr = str_replace( '.', ':', $addr ); |
| 478 | + if( IP::isIPv6( $addr ) ) |
| 479 | + return $addr; |
| 480 | + } |
479 | 481 | |
480 | | - // IPv4-mapped and IPv4-compatible IPv6 addresses |
481 | | - if ( preg_match( '/^' . RE_IPV6_V4_PREFIX . '(' . RE_IP_ADD . ')$/i', $addr, $m ) ) |
482 | | - return $m[1]; |
483 | | - if ( preg_match( '/^' . RE_IPV6_V4_PREFIX . RE_IPV6_WORD . ':' . RE_IPV6_WORD . '$/i', $addr, $m ) ) |
484 | | - return long2ip( ( hexdec( $m[1] ) << 16 ) + hexdec( $m[2] ) ); |
| 482 | + // IPv6 loopback address |
| 483 | + $m = array(); |
| 484 | + if ( preg_match( '/^0*' . RE_IPV6_GAP . '1$/', $addr, $m ) ) |
| 485 | + return '127.0.0.1'; |
485 | 486 | |
486 | | - return null; // give up |
| 487 | + // IPv4-mapped and IPv4-compatible IPv6 addresses |
| 488 | + if ( preg_match( '/^' . RE_IPV6_V4_PREFIX . '(' . RE_IP_ADD . ')$/i', $addr, $m ) ) |
| 489 | + return $m[1]; |
| 490 | + if ( preg_match( '/^' . RE_IPV6_V4_PREFIX . RE_IPV6_WORD . ':' . RE_IPV6_WORD . '$/i', $addr, $m ) ) |
| 491 | + return long2ip( ( hexdec( $m[1] ) << 16 ) + hexdec( $m[2] ) ); |
| 492 | + |
| 493 | + return null; // give up |
487 | 494 | } |
488 | 495 | } |
489 | 496 | |