diff --git src/wp-admin/includes/class-wp-community-events.php src/wp-admin/includes/class-wp-community-events.php
index 211d37ea5e..c075bbcfec 100644
|
|
class WP_Community_Events { |
236 | 236 | * or false on failure. |
237 | 237 | */ |
238 | 238 | public static function get_unsafe_client_ip() { |
239 | | $client_ip = false; |
| 239 | $client_ip = $netmask = false; |
240 | 240 | |
241 | 241 | // In order of preference, with the best ones for this purpose first. |
242 | 242 | $address_headers = array( |
… |
… |
class WP_Community_Events { |
263 | 263 | } |
264 | 264 | } |
265 | 265 | |
266 | | // These functions are not available on Windows until PHP 5.3. |
267 | | if ( function_exists( 'inet_pton' ) && function_exists( 'inet_ntop' ) ) { |
268 | | if ( 4 === strlen( inet_pton( $client_ip ) ) ) { |
269 | | $netmask = '255.255.255.0'; // ipv4. |
270 | | } else { |
271 | | $netmask = 'ffff:ffff:ffff:ffff:0000:0000:0000:0000'; // ipv6. |
| 266 | /* |
| 267 | * The filter extension is enabled by default, but some configurations |
| 268 | * disable it. Skipping this has the effect of disabling the IP geolocation, |
| 269 | * but the user can still manually enter their location, so it's an acceptable |
| 270 | * fallback. |
| 271 | */ |
| 272 | if ( $client_ip && function_exists( 'filter_var' ) ) { |
| 273 | if ( filter_var( $client_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) { |
| 274 | $ip_parts = explode( ':', $client_ip ); |
| 275 | $client_ip = $ip_parts[0]; |
| 276 | $netmask = '255.255.255.0'; |
| 277 | } elseif ( filter_var( $client_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) { |
| 278 | // todo - $client_ip = $client_ip with ports stripped off |
| 279 | $netmask = 'ffff:ffff:ffff:ffff:0000:0000:0000:0000'; |
272 | 280 | } |
| 281 | } |
273 | 282 | |
| 283 | // These functions are not available on Windows until PHP 5.3. |
| 284 | if ( $client_ip && $netmask && function_exists( 'inet_pton' ) && function_exists( 'inet_ntop' ) ) { |
274 | 285 | $client_ip = inet_ntop( inet_pton( $client_ip ) & inet_pton( $netmask ) ); |
275 | 286 | } |
276 | 287 | |
diff --git tests/phpunit/tests/admin/includesCommunityEvents.php tests/phpunit/tests/admin/includesCommunityEvents.php
index ed5cc2caee..c0acefce67 100644
|
|
class Test_WP_Community_Events extends WP_UnitTestCase { |
255 | 255 | 'filename' => '', |
256 | 256 | ); |
257 | 257 | } |
| 258 | |
| 259 | /** |
| 260 | * Test that get_unsafe_client_ip() properly anonymizes all possible address formats |
| 261 | * |
| 262 | * @ticket 41083 |
| 263 | * @since 4.8.1 |
| 264 | */ |
| 265 | public function test_get_unsafe_client_ip_anonymization() { |
| 266 | $test_cases = array( |
| 267 | '127.0.0.1' => '127.0.0.0', // Local IPv4 |
| 268 | '104.205.87.98' => '104.205.87.0', // Public IPv4 |
| 269 | '104.205.87.98:58749' => '104.205.87.0', // IPv4 with port |
| 270 | '1fff:0:a88:85a3::ac1f' => '1fff:0:a88:85a3::ac1f', // IPv6 |
| 271 | '[1fff:0:a88:85a3::ac1f]:8001' => '1fff:0:a88:85a3::ac1f', // IPv6 with port |
| 272 | // todo - add test cases from https://github.com/geertw/php-ip-anonymizer |
| 273 | ); |
| 274 | |
| 275 | foreach ( $test_cases as $raw_ip => $expected_result ) { |
| 276 | $_GET['REMOTE_ADDR'] = $raw_ip; |
| 277 | $actual_result = WP_Community_Events::get_unsafe_client_ip(); |
| 278 | |
| 279 | $this->assertEquals( $expected_result, $actual_result ); |
| 280 | } |
| 281 | } |
258 | 282 | } |