Fix Block::newLoad for IPv6 range blocks - follow-up to Ie8bebd8
authorThalia <thalia.e.chan@googlemail.com>
Wed, 8 May 2019 17:49:18 +0000 (12:49 -0500)
committerThalia <thalia.e.chan@googlemail.com>
Wed, 8 May 2019 18:22:46 +0000 (13:22 -0500)
Previously, the size of the range is calculated by finding the
difference between that start and end addresses, converted into
decimal. This fails when the numbers are too large.

Instead, use parsing methods from IP class to avoid having to
handle large numbers.

Bug: T222246
Change-Id: If466139c42c4ac832a9506c80bdb228e9da39638

includes/Block.php
tests/phpunit/includes/BlockTest.php

index 472c36e..5b0d256 100644 (file)
@@ -322,13 +322,13 @@ class Block extends AbstractBlock {
                        if ( $block->getType() == self::TYPE_RANGE ) {
                                # This is the number of bits that are allowed to vary in the block, give
                                # or take some floating point errors
-                               $prefix = 'v6-';
-                               $end = Wikimedia\base_convert( ltrim( $block->getRangeEnd(), $prefix ), 16, 10 );
-                               $start = Wikimedia\base_convert( ltrim( $block->getRangeStart(), $prefix ), 16, 10 );
-                               $size = log( $end - $start + 1, 2 );
+                               $target = $block->getTarget();
+                               $max = IP::isIPv6( $target ) ? 128 : 32;
+                               list( $network, $bits ) = IP::parseCIDR( $target );
+                               $size = $max - $bits;
 
                                # Rank a range block covering a single IP equally with a single-IP block
-                               $score = self::TYPE_RANGE - 1 + ( $size / 128 );
+                               $score = self::TYPE_RANGE - 1 + ( $size / $max );
 
                        } else {
                                $score = $block->getType();
index dac3b87..3dc5e78 100644 (file)
@@ -175,21 +175,31 @@ class BlockTest extends MediaWikiLangTestCase {
                                '0.0.0.0',
                                '0.0.0.0'
                        ],
-                       'Blocks to wide IPv6 range and IP' => [
-                               [ '0:0:0:0:0:0:0:0/19', '0:0:0:0:0:0:0:0' ],
-                               '0:0:0:0:0:0:0:0',
-                               '0:0:0:0:0:0:0:0'
-                       ],
                        'Blocks to narrow IPv4 range and IP' => [
                                [ '0.0.0.0/31', '0.0.0.0' ],
                                '0.0.0.0',
                                '0.0.0.0'
                        ],
+                       'Blocks to wide IPv6 range and IP' => [
+                               [ '0:0:0:0:0:0:0:0/19', '0:0:0:0:0:0:0:0' ],
+                               '0:0:0:0:0:0:0:0',
+                               '0:0:0:0:0:0:0:0'
+                       ],
                        'Blocks to narrow IPv6 range and IP' => [
                                [ '0:0:0:0:0:0:0:0/127', '0:0:0:0:0:0:0:0' ],
                                '0:0:0:0:0:0:0:0',
                                '0:0:0:0:0:0:0:0'
                        ],
+                       'Blocks to wide IPv6 range and IP, large numbers' => [
+                               [ '2000:DEAD:BEEF:A:0:0:0:0/19', '2000:DEAD:BEEF:A:0:0:0:0' ],
+                               '2000:DEAD:BEEF:A:0:0:0:0',
+                               '2000:DEAD:BEEF:A:0:0:0:0'
+                       ],
+                       'Blocks to narrow IPv6 range and IP, large numbers' => [
+                               [ '2000:DEAD:BEEF:A:0:0:0:0/127', '2000:DEAD:BEEF:A:0:0:0:0' ],
+                               '2000:DEAD:BEEF:A:0:0:0:0',
+                               '2000:DEAD:BEEF:A:0:0:0:0'
+                       ],
                ];
        }