Skip to content

Commit 28e8709

Browse files
mariushochChad Horohoe
authored and
Chad Horohoe
committed
Fix IP::toHex for IPv4 addresses with a double/triple 0 block
Bug: T97897 Signed-off-by: Chad Horohoe <[email protected]> Change-Id: I5c0a37be42ae2c5091ead487a6d19f6e0dd89b36
1 parent 3740fde commit 28e8709

File tree

2 files changed

+44
-11
lines changed

2 files changed

+44
-11
lines changed

includes/utils/IP.php

+16-6
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,9 @@ public static function isValidBlock( $ipblock ) {
132132

133133
/**
134134
* Convert an IP into a verbose, uppercase, normalized form.
135-
* IPv6 addresses in octet notation are expanded to 8 words.
136-
* IPv4 addresses are just trimmed.
135+
* Both IPv4 and IPv6 addresses are trimmed. Additionally,
136+
* IPv6 addresses in octet notation are expanded to 8 words;
137+
* IPv4 addresses have leading zeros, in each octet, removed.
137138
*
138139
* @param string $ip IP address in quad or octet form (CIDR or not).
139140
* @return string
@@ -143,8 +144,16 @@ public static function sanitizeIP( $ip ) {
143144
if ( $ip === '' ) {
144145
return null;
145146
}
146-
if ( self::isIPv4( $ip ) || !self::isIPv6( $ip ) ) {
147-
return $ip; // nothing else to do for IPv4 addresses or invalid ones
147+
/* If not an IP, just return trimmed value, since sanitizeIP() is called
148+
* in a number of contexts where usernames are supplied as input.
149+
*/
150+
if ( !self::isIPAddress($ip) ) {
151+
return $ip;
152+
}
153+
if ( self::isIPv4( $ip ) ) {
154+
// Remove leading 0's from octet representation of IPv4 address
155+
$ip = preg_replace( '/(?:^|(?<=\.))0+(?=[1-9]|0\.|0$)/', '', $ip );
156+
return $ip;
148157
}
149158
// Remove any whitespaces, convert to upper case
150159
$ip = strtoupper( $ip );
@@ -399,8 +408,9 @@ public static function toHex( $ip ) {
399408
if ( self::isIPv6( $ip ) ) {
400409
$n = 'v6-' . self::IPv6ToRawHex( $ip );
401410
} elseif ( self::isIPv4( $ip ) ) {
402-
// Bug 60035: an IP with leading 0's fails in ip2long sometimes (e.g. *.08)
403-
$ip = preg_replace( '/(?<=\.)0+(?=[1-9])/', '', $ip );
411+
// T62035/T97897: An IP with leading 0's fails in ip2long sometimes (e.g. *.08),
412+
// also double/triple 0 needs to be changed to just a single 0 for ip2long.
413+
$ip = self::sanitizeIP( $ip );
404414
$n = ip2long( $ip );
405415
if ( $n < 0 ) {
406416
$n += pow( 2, 32 );

tests/phpunit/includes/utils/IPTest.php

+28-5
Original file line numberDiff line numberDiff line change
@@ -307,12 +307,34 @@ public function provideInvalidBlocks() {
307307
}
308308

309309
/**
310-
* Improve IP::sanitizeIP() code coverage
311-
* @todo Most probably incomplete
310+
* @covers IP::sanitizeIP
311+
* @dataProvider provideSanitizeIP
312312
*/
313-
public function testSanitizeIP() {
314-
$this->assertNull( IP::sanitizeIP( '' ) );
315-
$this->assertNull( IP::sanitizeIP( ' ' ) );
313+
public function testSanitizeIP( $expected, $input ) {
314+
$result = IP::sanitizeIP( $input );
315+
$this->assertEquals( $expected, $result );
316+
}
317+
318+
/**
319+
* Provider for IP::testSanitizeIP()
320+
*/
321+
public static function provideSanitizeIP() {
322+
return array(
323+
array( '0.0.0.0', '0.0.0.0' ),
324+
array( '0.0.0.0', '00.00.00.00' ),
325+
array( '0.0.0.0', '000.000.000.000' ),
326+
array( '141.0.11.253', '141.000.011.253' ),
327+
array( '1.2.4.5', '1.2.4.5' ),
328+
array( '1.2.4.5', '01.02.04.05' ),
329+
array( '1.2.4.5', '001.002.004.005' ),
330+
array( '10.0.0.1', '010.0.000.1' ),
331+
array( '80.72.250.4', '080.072.250.04' ),
332+
array( 'Foo.1000.00', 'Foo.1000.00'),
333+
array( 'Bar.01', 'Bar.01'),
334+
array( 'Bar.010', 'Bar.010'),
335+
array( null, ''),
336+
array( null, ' ')
337+
);
316338
}
317339

318340
/**
@@ -336,6 +358,7 @@ public static function provideToHex() {
336358
array( '80000000', '128.0.0.0' ),
337359
array( 'DEADCAFE', '222.173.202.254' ),
338360
array( 'FFFFFFFF', '255.255.255.255' ),
361+
array( '8D000BFD', '141.000.11.253' ),
339362
array( false, 'IN.VA.LI.D' ),
340363
array( 'v6-00000000000000000000000000000001', '::1' ),
341364
array( 'v6-20010DB885A3000000008A2E03707334', '2001:0db8:85a3:0000:0000:8a2e:0370:7334' ),

0 commit comments

Comments
 (0)