*Fix isInRange(), remove cruft, add "ipv-6" prefix to toHex() and parseRange6(),...
authorAaron Schulz <aaron@users.mediawiki.org>
Wed, 28 Mar 2007 05:39:06 +0000 (05:39 +0000)
committerAaron Schulz <aaron@users.mediawiki.org>
Wed, 28 Mar 2007 05:39:06 +0000 (05:39 +0000)
includes/Block.php
includes/IP.php
includes/SpecialBlockip.php

index ee75fb1..d1f96e6 100644 (file)
@@ -23,7 +23,8 @@ class Block
        const EB_RANGE_ONLY = 4;
 
        function __construct( $address = '', $user = 0, $by = 0, $reason = '',
-               $timestamp = '' , $auto = 0, $expiry = '', $anonOnly = 0, $createAccount = 0, $enableAutoblock = 0, $hideName = 0 )
+               $timestamp = '' , $auto = 0, $expiry = '', $anonOnly = 0, $createAccount = 0, $enableAutoblock = 0, 
+               $hideName = 0 )
        {
                $this->mId = 0;
                # Expand valid IPv6 addresses
@@ -640,39 +641,34 @@ class Block
        }
        
        /** 
-        * Gets rid of uneeded numbers in quad-dotted IP strings
+        * Gets rid of uneeded numbers in quad-dotted/octet IP strings
         * For example, 127.111.113.151/24 -> 127.111.113.0/24
         */
        static function normaliseRange( $range ) {
-               // Use IPv6 functions if needed
-               if ( IP::isIPv6($range) ) return self::normaliseRange6( $range );
                $parts = explode( '/', $range );
                if ( count( $parts ) == 2 ) {
-                       $shift = 32 - $parts[1];
-                       $ipint = IP::toUnsigned( $parts[0] );
-                       $ipint = $ipint >> $shift << $shift;
-                       $newip = long2ip( $ipint );
-                       $range = "$newip/{$parts[1]}";
-               }
-               return $range;
-       }
-       
-       // For IPv6
-       static function normaliseRange6( $range ) {
-               $parts = explode( '/', $range );
-               if ( count( $parts ) == 2 ) {
-                       $bits = $parts[1];
-                       $ipint = IP::toUnsigned6( $parts[0] );
-                       # Native 32 bit functions WONT work here!!!
-                       # Convert to a padded binary number
-                       $network = wfBaseConvert( $ipint, 10, 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 );
-                       # Reform octet address
-                       $newip = IP::toOctet( $network );
-                       $range = "$newip/{$parts[1]}";
+                       // IPv6
+                       if ( IP::isIPv6($range) && $parts[1] >= 64 && $parts[1] <= 128 ) {
+                               $bits = $parts[1];
+                               $ipint = IP::toUnsigned6( $parts[0] );
+                               # Native 32 bit functions WONT work here!!!
+                               # Convert to a padded binary number
+                               $network = wfBaseConvert( $ipint, 10, 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 );
+                               # Reform octet address
+                               $newip = IP::toOctet( $network );
+                               $range = "$newip/{$parts[1]}";
+                       } // IPv4
+                       else if ( IP::isIPv4($range) && $parts[1] >= 16 && $parts[1] <= 32 ) {
+                               $shift = 32 - $parts[1];
+                               $ipint = IP::toUnsigned( $parts[0] );
+                               $ipint = $ipint >> $shift << $shift;
+                               $newip = long2ip( $ipint );
+                               $range = "$newip/{$parts[1]}";
+                       }
                }
                return $range;
        }
index 9567f1e..748a1f0 100644 (file)
@@ -89,13 +89,15 @@ class IP {
                $ip = explode(':', self::sanitizeIP( $ip ) );
                $r_ip = '';
                foreach ($ip as $v) {
-                       $r_ip .= wfBaseConvert( $v, 16, 2, 16);
+                       $r_ip .= str_pad( $v, 4, 0, STR_PAD_LEFT );
         }
-               return wfBaseConvert($r_ip, 2, 10);
+        $r_ip = wfBaseConvert( $r_ip, 16, 10 );
+               return $r_ip;
        }
        
        /**
         * Given an IPv6 address in octet notation, returns the expanded octet.
+        * IPv4 IPs will be trimmed, thats it...
         * @param $ip octet ipv6 IP address.
         * @return string 
         */     
@@ -107,18 +109,14 @@ class IP {
                if ( !self::isIPv6($ip) ) return $ip;
                // Remove any whitespaces, convert to upper case
                $ip = strtoupper( trim($ip) );
-               // Expand zero abbreviations
-               if ( substr_count($ip, '::') ) {
+               // Expand zero abbreviations
+               if ( strpos( $ip, '::' ) !== false ) {
                $ip = str_replace('::', str_repeat(':0', 8 - substr_count($ip, ':')) . ':', $ip);
        }
        // For IPs that start with "::", correct the final IP so that it starts with '0' and not ':'
-       if ( strpos( $ip, ':' ) === 0 ) $ip = "0$ip";
+       if ( $ip[0] == ':' ) $ip = "0$ip";
        // Remove leading zereos from each bloc as needed
-       $ip = explode( ':', $ip );
-       for ( $n=0; $n < count($ip); $n++ ) {
-               $ip[$n] = preg_replace( '/^0+' . RE_IPV6_WORD . '/', '$1', $ip[$n] );
-       }
-       $ip = implode( ':', $ip );
+       $ip = preg_replace( '/(^|:)0+' . RE_IPV6_WORD . '/', '$1$2', $ip );
        return $ip;
        }
        
@@ -128,14 +126,15 @@ class IP {
         * @return string 
         */
        public static function toOctet( $ip_int ) {
-               // Convert integer to binary
-               $ip_int = wfBaseConvert($ip_int, 10, 2, 128);
+               // Convert to padded uppercase hex
+               $ip_hex = wfBaseConvert($ip_int, 10, 16, 32, false);
                // Seperate into 8 octets
-               $ip_oct = wfBaseConvert( substr( $ip_int, 0, 16 ), 2, 16, 1, false );
+               $ip_oct = substr( $ip_hex, 0, 4 );
                for ($n=1; $n < 8; $n++) {
-                       // Convert to uppercase hex, and add ":" marks, with NO leading zeroes
-                       $ip_oct .= ':' . wfBaseConvert( substr($ip_int, 16*$n, 16), 2, 16, 1, false );
+                       $ip_oct .= ':' . substr($ip_hex, 4*$n, 4);
                }
+               // NO leading zeroes
+               $ip_oct = preg_replace( '/(^|:)0+' . RE_IPV6_WORD . '/', '$1$2', $ip_oct );
                return $ip_oct;
        }
 
@@ -167,7 +166,6 @@ class IP {
                        $network = false;
                        $bits = false;
                }
-               
                return array( $network, $bits );
        }
        
@@ -197,6 +195,8 @@ class IP {
                                $end = str_pad( substr( $end, 0, $bits ), 128, 1, STR_PAD_RIGHT );
                                # Convert to hex
                                $end = wfBaseConvert( $end, 2, 16, 32, false );
+                               # see toHex() comment
+                               $start = "ipv6-$start"; $end = "ipv6-$end";
                        }
                } elseif ( strpos( $range, '-' ) !== false ) {
                        # Explicit range
@@ -208,6 +208,8 @@ class IP {
                                $start = wfBaseConvert( $start, 10, 16, 32, false );
                                $end = wfBaseConvert( $end, 10, 16, 32, false );
                        }
+                       # see toHex() comment
+                       $start = "ipv6-$start"; $end = "ipv6-$end";
                } else {
                        # Single IP
                        $start = $end = self::toHex( $range );
@@ -305,13 +307,13 @@ class IP {
        public static function toHex( $ip ) {
                $n = self::toUnsigned( $ip );
                if ( $n !== false ) {
-                       $n = ( self::isIPv6($ip) ) ? wfBaseConvert( $n, 10, 16, 32, false ) : wfBaseConvert( $n, 10, 16, 8, false );
+                       $n = ( self::isIPv6($ip) ) ? "v6-" . wfBaseConvert( $n, 10, 16, 32, false ) : wfBaseConvert( $n, 10, 16, 8, false );
                }
                return $n;
        }
 
        /**
-        * Given an IP address in dotted-quad notation, returns an unsigned integer.
+        * Given an IP address in dotted-quad/octet notation, returns an unsigned integer.
         * Like ip2long() except that it actually works and has a consistent error return value.
         * Comes from ProxyTools.php
         * @param $ip Quad dotted IP address.
@@ -382,12 +384,16 @@ class IP {
 
        /**
         * Given a string range in a number of formats, return the start and end of 
-        * the range in hexadecimal. For IPv4.
+        * the range in hexadecimal.
         *
         * Formats are:
         *     1.2.3.4/24          CIDR
         *     1.2.3.4 - 1.2.3.5   Explicit range
         *     1.2.3.4             Single IP
+        * 
+        *     2001:0db8:85a3::7344/96                                   CIDR
+        *     2001:0db8:85a3::7344 - 2001:0db8:85a3::7344   Explicit range
+        *     2001:0db8:85a3::7344/96                                   Single IP
         * @return array(string, int)
         */
        public static function parseRange( $range ) {
@@ -433,8 +439,8 @@ class IP {
      */
     public static function isInRange( $addr, $range ) {
     // Convert to IPv6 if needed
-        $unsignedIP = self::toUnsigned( $addr );
-        list( $start, $end ) = self::parseRange($range );
+        $unsignedIP = self::toHex( $addr );
+        list( $start, $end ) = self::parseRange( $range );
         return (($unsignedIP >= $start) && ($unsignedIP <= $end));
     }
 
index 27729f2..602f6db 100644 (file)
@@ -45,7 +45,7 @@ class IPBlockForm {
        var $BlockAddress, $BlockExpiry, $BlockReason;
 
        function IPBlockForm( $par ) {
-               global $wgRequest;
+               global $wgRequest, $wgUser;
 
                $this->BlockAddress = $wgRequest->getVal( 'wpBlockAddress', $wgRequest->getVal( 'ip', $par ) );
                $this->BlockAddress = strtr( $this->BlockAddress, '_', ' ' );
@@ -59,6 +59,8 @@ class IPBlockForm {
                $this->BlockAnonOnly = $wgRequest->getBool( 'wpAnonOnly', $byDefault );
                $this->BlockCreateAccount = $wgRequest->getBool( 'wpCreateAccount', $byDefault );
                $this->BlockEnableAutoblock = $wgRequest->getBool( 'wpEnableAutoblock', $byDefault );
+               # Re-check user's rights to hide names, very serious, defaults to 0
+               $this->BlockHideName = $wgRequest->getBool( 'wpHideName', 0 ) && $wgUser->isAllowed( 'hideuser' );
        }
 
        function showForm( $err ) {
@@ -131,6 +133,7 @@ class IPBlockForm {
                        </td>
                        ");
                }
+               
                $wgOut->addHTML("
                </tr>
                <tr id='wpBlockOther'>
@@ -150,31 +153,46 @@ class IPBlockForm {
                <tr id='wpAnonOnlyRow'>
                        <td>&nbsp;</td>
                        <td align=\"left\">
-                               " . wfCheckLabel( wfMsg( 'ipbanononly' ),
+                               " . wfCheckLabel( wfMsgHtml( 'ipbanononly' ),
                                        'wpAnonOnly', 'wpAnonOnly', $this->BlockAnonOnly,
-                                       array( 'tabindex' => 4 ) ) . "
+                                       array( 'tabindex' => '4' ) ) . "
                        </td>
                </tr>
                <tr id='wpCreateAccountRow'>
                        <td>&nbsp;</td>
                        <td align=\"left\">
-                               " . wfCheckLabel( wfMsg( 'ipbcreateaccount' ),
+                               " . wfCheckLabel( wfMsgHtml( 'ipbcreateaccount' ),
                                        'wpCreateAccount', 'wpCreateAccount', $this->BlockCreateAccount,
-                                       array( 'tabindex' => 5 ) ) . "
+                                       array( 'tabindex' => '5' ) ) . "
                        </td>
                </tr>
                <tr id='wpEnableAutoblockRow'>
                        <td>&nbsp;</td>
                        <td align=\"left\">
-                               " . wfCheckLabel( wfMsg( 'ipbenableautoblock' ),
+                               " . wfCheckLabel( wfMsgHtml( 'ipbenableautoblock' ),
                                                'wpEnableAutoblock', 'wpEnableAutoblock', $this->BlockEnableAutoblock,
-                                                       array( 'tabindex' => 6 ) ) . "
+                                                       array( 'tabindex' => '6' ) ) . "
                        </td>
                </tr>
+               ");
+               // Allow some users to hide name from block log, blocklist and listusers
+               if ( $wgUser->isAllowed( 'hideuser' ) ) {
+                       $wgOut->addHTML("
+                       <tr>
+                       <td>&nbsp;</td>
+                               <td align=\"left\">
+                                       " . wfCheckLabel( wfMsgHtml( 'ipbhidename' ),
+                                                       'wpHideName', 'wpHideName', $this->BlockHideName,
+                                                               array( 'tabindex' => '6' ) ) . "
+                               </td>
+                       </tr>
+                       ");
+               }
+               $wgOut->addHTML("
                <tr>
                        <td style='padding-top: 1em'>&nbsp;</td>
                        <td style='padding-top: 1em' align=\"left\">
-                               " . Xml::submitButton( wfMsg( 'ipbsubmit' ),
+                               " . Xml::submitButton( wfMsgHtml( 'ipbsubmit' ),
                                                        array( 'name' => 'wpBlock', 'tabindex' => '7' ) ) . "
                        </td>
                </tr>
@@ -213,7 +231,7 @@ class IPBlockForm {
                        if ( preg_match( "/^($rxIP4)\\/(\\d{1,2})$/", $this->BlockAddress, $matches ) ) {
                                # IPv4
                                if ( $wgSysopRangeBans ) {
-                                       if ( !IP::isIPv4( $this->BlockAddress ) || $matches[2] > 31 || $matches[2] < 16 ) {
+                                       if ( !IP::isIPv4( $this->BlockAddress ) || $matches[2] < 16 || $matches[2] > 32 ) {
                                                $this->showForm( wfMsg( 'ip_range_invalid' ) );
                                                return;
                                        }
@@ -226,11 +244,11 @@ class IPBlockForm {
                        } else if ( preg_match( "/^($rxIP6)\\/(\\d{1,3})$/", $this->BlockAddress, $matches ) ) {
                                # IPv6
                                if ( $wgSysopRangeBans ) {
-                                       if ( !IP::isIPv6( $this->BlockAddress ) || $matches[2] > 127 || $matches[2] < 64 ) {
+                                       if ( !IP::isIPv6( $this->BlockAddress ) || $matches[2] < 64 || $matches[2] > 128 ) {
                                                $this->showForm( wfMsg( 'ip_range_invalid' ) );
                                                return;
                                        }
-                                       $this->BlockAddress = Block::normaliseRange6( $this->BlockAddress );
+                                       $this->BlockAddress = Block::normaliseRange( $this->BlockAddress );
                                } else {
                                        # Range block illegal
                                        $this->showForm( wfMsg( 'range_block_disabled' ) );
@@ -283,7 +301,7 @@ class IPBlockForm {
 
                $block = new Block( $this->BlockAddress, $userId, $wgUser->getID(),
                        $this->BlockReason, wfTimestampNow(), 0, $expiry, $this->BlockAnonOnly,
-                       $this->BlockCreateAccount, $this->BlockEnableAutoblock );
+                       $this->BlockCreateAccount, $this->BlockEnableAutoblock, $this->BlockHideName);
 
                if (wfRunHooks('BlockIp', array(&$block, &$wgUser))) {
 
@@ -300,8 +318,9 @@ class IPBlockForm {
                        $logParams[] = $expirestr;
                        $logParams[] = $this->blockLogFlags();
 
-                       # Make log entry
-                       $log = new LogPage( 'block' );
+                       # Make log entry, if the name is hidden, put it in the oversight log
+                       $log_type = ($this->BlockHideName) ? 'oversight' : 'block';
+                       $log = new LogPage( $log_type );
                        $log->addEntry( 'block', Title::makeTitle( NS_USER, $this->BlockAddress ),
                          $this->BlockReason, $logParams );