summaryrefslogtreecommitdiff
path: root/includes/utils/IP.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/utils/IP.php')
-rw-r--r--includes/utils/IP.php28
1 files changed, 21 insertions, 7 deletions
diff --git a/includes/utils/IP.php b/includes/utils/IP.php
index 4441236d..13586f3c 100644
--- a/includes/utils/IP.php
+++ b/includes/utils/IP.php
@@ -21,6 +21,8 @@
* @author Antoine Musso "<hashar at free dot fr>", Aaron Schulz
*/
+use IPSet\IPSet;
+
// Some regex definition to "play" with IP address and IP address blocks
// An IPv4 address is made of 4 bytes from x00 to xFF which is d0 to d255
@@ -130,8 +132,9 @@ class IP {
/**
* Convert an IP into a verbose, uppercase, normalized form.
- * IPv6 addresses in octet notation are expanded to 8 words.
- * IPv4 addresses are just trimmed.
+ * Both IPv4 and IPv6 addresses are trimmed. Additionally,
+ * IPv6 addresses in octet notation are expanded to 8 words;
+ * IPv4 addresses have leading zeros, in each octet, removed.
*
* @param string $ip IP address in quad or octet form (CIDR or not).
* @return string
@@ -141,8 +144,16 @@ class IP {
if ( $ip === '' ) {
return null;
}
- if ( self::isIPv4( $ip ) || !self::isIPv6( $ip ) ) {
- return $ip; // nothing else to do for IPv4 addresses or invalid ones
+ /* If not an IP, just return trimmed value, since sanitizeIP() is called
+ * in a number of contexts where usernames are supplied as input.
+ */
+ if ( !self::isIPAddress($ip) ) {
+ return $ip;
+ }
+ if ( self::isIPv4( $ip ) ) {
+ // Remove leading 0's from octet representation of IPv4 address
+ $ip = preg_replace( '/(?:^|(?<=\.))0+(?=[1-9]|0\.|0$)/', '', $ip );
+ return $ip;
}
// Remove any whitespaces, convert to upper case
$ip = strtoupper( $ip );
@@ -240,7 +251,7 @@ class IP {
* A bare IPv6 address is accepted despite the lack of square brackets.
*
* @param string $both The string with the host and port
- * @return array
+ * @return array|false Array normally, false on certain failures
*/
public static function splitHostAndPort( $both ) {
if ( substr( $both, 0, 1 ) === '[' ) {
@@ -375,6 +386,8 @@ class IP {
'127.0.0.0/8', # loopback
'fc00::/7', # RFC 4193 (local)
'0:0:0:0:0:0:0:1', # loopback
+ '169.254.0.0/16', # link-local
+ 'fe80::/10', # link-local
) );
}
return !$privateSet->match( $ip );
@@ -395,8 +408,9 @@ class IP {
if ( self::isIPv6( $ip ) ) {
$n = 'v6-' . self::IPv6ToRawHex( $ip );
} elseif ( self::isIPv4( $ip ) ) {
- // Bug 60035: an IP with leading 0's fails in ip2long sometimes (e.g. *.08)
- $ip = preg_replace( '/(?<=\.)0+(?=[1-9])/', '', $ip );
+ // T62035/T97897: An IP with leading 0's fails in ip2long sometimes (e.g. *.08),
+ // also double/triple 0 needs to be changed to just a single 0 for ip2long.
+ $ip = self::sanitizeIP( $ip );
$n = ip2long( $ip );
if ( $n < 0 ) {
$n += pow( 2, 32 );