From: Thalia Date: Fri, 8 Mar 2019 23:08:09 +0000 (+0000) Subject: Fix Block::newLoad for IPv6 range blocks X-Git-Tag: 1.34.0-rc.0~1780^2 X-Git-Url: http://git.cyclocoop.org/%28?a=commitdiff_plain;h=f01cac1d17b5814bda595b2854c403164f5577ef;p=lhc%2Fweb%2Fwiklou.git Fix Block::newLoad for IPv6 range blocks If Block::newLoad finds multiple IP range blocks, the block with the narrowest range is chosen. In order to determine this, the start and end of the range are converted to decimal. Prior to this patch, this does not work for IPv6 because the converter does not handle the 'v6-' prefix on IPv6 addresses, so remove this. Bug: T222246 Change-Id: Ie8bebd86d8b4a4d2c7bffd1edaa09ec5ba207303 --- diff --git a/includes/Block.php b/includes/Block.php index 3f17d843b8..3b236038b3 100644 --- a/includes/Block.php +++ b/includes/Block.php @@ -388,8 +388,9 @@ class Block { 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 - $end = Wikimedia\base_convert( $block->getRangeEnd(), 16, 10 ); - $start = Wikimedia\base_convert( $block->getRangeStart(), 16, 10 ); + $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 ); # This has the nice property that a /32 block is ranked equally with a diff --git a/tests/phpunit/includes/BlockTest.php b/tests/phpunit/includes/BlockTest.php index df3de4a336..61e3e7c2af 100644 --- a/tests/phpunit/includes/BlockTest.php +++ b/tests/phpunit/includes/BlockTest.php @@ -131,6 +131,68 @@ class BlockTest extends MediaWikiLangTestCase { ]; } + /** + * @dataProvider provideNewFromTargetRangeBlocks + * @covers Block::newFromTarget + */ + public function testNewFromTargetRangeBlocks( $targets, $ip, $expectedTarget ) { + $blocker = $this->getTestSysop()->getUser(); + + foreach ( $targets as $target ) { + $block = new Block(); + $block->setTarget( $target ); + $block->setBlocker( $blocker ); + $block->insert(); + } + + // Should find the block with the narrowest range + $blockTarget = Block::newFromTarget( $this->getTestUser()->getUser(), $ip )->getTarget(); + $this->assertSame( + $blockTarget instanceof User ? $blockTarget->getName() : $blockTarget, + $expectedTarget + ); + + foreach ( $targets as $target ) { + $block = Block::newFromTarget( $target ); + $block->delete(); + } + } + + function provideNewFromTargetRangeBlocks() { + return [ + 'Blocks to IPv4 ranges' => [ + [ '0.0.0.0/20', '0.0.0.0/30', '0.0.0.0/25' ], + '0.0.0.0', + '0.0.0.0/30' + ], + 'Blocks to IPv6 ranges' => [ + [ '0:0:0:0:0:0:0:0/20', '0:0:0:0:0:0:0:0/30', '0:0:0:0:0:0:0:0/25' ], + '0:0:0:0:0:0:0:0', + '0:0:0:0:0:0:0:0/30' + ], + 'Blocks to wide IPv4 range and IP' => [ + [ '0.0.0.0/16', '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 IPv4 range and IP' => [ + [ '0.0.0.0/31', '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' + ], + ]; + } + /** * @covers Block::appliesToRight */