Merge "Add $revision to TitleMoveCompleting for completeness"
[lhc/web/wiklou.git] / includes / utils / IP.php
index 666660a..8abca5b 100644 (file)
@@ -132,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
@@ -143,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 );
@@ -399,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 );
@@ -411,7 +421,7 @@ class IP {
                                }
                        }
                        if ( $n !== false ) {
-                               # Floating points can handle the conversion; faster than wfBaseConvert()
+                               # Floating points can handle the conversion; faster than Wikimedia\base_convert()
                                $n = strtoupper( str_pad( base_convert( $n, 10, 16 ), 8, '0', STR_PAD_LEFT ) );
                        }
                } else {
@@ -551,11 +561,11 @@ class IP {
                        } else {
                                # Native 32 bit functions WONT work here!!!
                                # Convert to a padded binary number
-                               $network = wfBaseConvert( $network, 16, 2, 128 );
+                               $network = Wikimedia\base_convert( $network, 16, 2, 128 );
                                # Truncate the last (128-$bits) bits and replace them with zeros
                                $network = str_pad( substr( $network, 0, $bits ), 128, 0, STR_PAD_RIGHT );
                                # Convert back to an integer
-                               $network = wfBaseConvert( $network, 2, 10 );
+                               $network = Wikimedia\base_convert( $network, 2, 10 );
                        }
                } else {
                        $network = false;
@@ -587,13 +597,13 @@ class IP {
                        if ( $network === false ) {
                                $start = $end = false;
                        } else {
-                               $start = wfBaseConvert( $network, 10, 16, 32, false );
+                               $start = Wikimedia\base_convert( $network, 10, 16, 32, false );
                                # Turn network to binary (again)
-                               $end = wfBaseConvert( $network, 10, 2, 128 );
+                               $end = Wikimedia\base_convert( $network, 10, 2, 128 );
                                # Truncate the last (128-$bits) bits and replace them with ones
                                $end = str_pad( substr( $end, 0, $bits ), 128, 1, STR_PAD_RIGHT );
                                # Convert to hex
-                               $end = wfBaseConvert( $end, 2, 16, 32, false );
+                               $end = Wikimedia\base_convert( $end, 2, 16, 32, false );
                                # see toHex() comment
                                $start = "v6-$start";
                                $end = "v6-$end";
@@ -659,7 +669,7 @@ class IP {
         * unusual representations may be added later.
         *
         * @param string $addr Something that might be an IP address
-        * @return string Valid dotted quad IPv4 address or null
+        * @return string|null Valid dotted quad IPv4 address or null
         */
        public static function canonicalize( $addr ) {
                // remove zone info (bug 35738)
@@ -713,7 +723,7 @@ class IP {
        /**
         * Checks if an IP is a trusted proxy provider.
         * Useful to tell if X-Forwarded-For data is possibly bogus.
-        * Squid cache servers for the site are whitelisted.
+        * CDN cache servers for the site are whitelisted.
         * @since 1.24
         *
         * @param string $ip