WordPress.org

Make WordPress Core

Ticket #43545: 43545.3.diff

File 43545.3.diff, 5.8 KB (added by azaozz, 18 months ago)
  • src/wp-includes/functions.php

     
    61276127                ), $email_change_email['message'], $email_change_email['headers']
    61286128        );
    61296129}
     6130
     6131/**
     6132 * Return an anonymized IPV4 or IPV6 address.
     6133 *
     6134 * @since 5.0.0
     6135 *
     6136 * @param  string $ip_addr The IPv4 or IPv6 address to be anonymized.
     6137 * @return string          The anonymized IP address.
     6138 */
     6139function wp_privacy_anonymize_ip( $ip_addr ) {
     6140        $ip_prefix = '';
     6141        $is_ipv4   = ( 3 === substr_count( $ip_addr, '.' ) );
     6142        $is_ipv6   = substr_count( $ip_addr, ':' ) > 1;
     6143
     6144        if ( $is_ipv6 && $is_ipv4 ) {
     6145                // IPv6 compatibility mode, temporarily strip the IPv6 part, and treat it like IPv4.
     6146                $ip_prefix = '::ffff:';
     6147                $ip_addr   = preg_replace( '/^\[?[0-9a-f:]*:/i', '', $ip_addr );
     6148                $ip_addr   = str_replace( ']', '', $ip_addr );
     6149                $is_ipv6   = false;
     6150        }
     6151
     6152        if ( $is_ipv6 ) {
     6153                // IPv6 addresses will always be enclosed in [] if there's a port.
     6154                $ip_start = 1;
     6155                $ip_end   = (int) strpos( $ip_addr, ']' ) - 1;
     6156                $netmask  = 'ffff:ffff:ffff:ffff:0000:0000:0000:0000';
     6157
     6158                // Strip the port (and [] from IPv6 addresses), if they exist.
     6159                if ( $ip_end > 0 ) {
     6160                        $ip_addr = substr( $ip_addr, $ip_start, $ip_end );
     6161                }
     6162
     6163                // Partially anonymize the IP by reducing it to the corresponding network ID.
     6164                // This basically zeros the last eight octets of an IPV6 address.
     6165                // Note inet_pton and inet_ntop were not available on Windows platforms until PHP 5.3.0.
     6166                if ( function_exists( 'inet_pton' ) && function_exists( 'inet_ntop' ) ) {
     6167                        $ip_addr = inet_ntop( inet_pton( $ip_addr ) & inet_pton( $netmask ) );
     6168                } else {
     6169                        return '0.0.0.0';
     6170                }
     6171        } elseif ( $is_ipv4 ) {
     6172                // Strip any port and partially anonymize the IP.
     6173                $last_octet_position = strrpos( $ip_addr, '.' );
     6174                $ip_addr             = substr( $ip_addr, 0, $last_octet_position ) . '.0';
     6175        } else {
     6176                return '0.0.0.0';
     6177        }
     6178
     6179        // Restore the IPv6 prefix to compatibility mode addresses.
     6180        return $ip_prefix . $ip_addr;
     6181}
     6182
     6183/**
     6184 * Return uniform "anonymous" data by type.
     6185 *
     6186 * @since 5.0.0
     6187 *
     6188 * @param  string $data Optional The data to be anonymized.
     6189 * @param  string $type Optional The type of data to be anonymized.
     6190 * @return string                The anonymous data for the requested type.
     6191 */
     6192function wp_privacy_anonymize_data( $data = '', $type = '' ) {
     6193
     6194        switch ( $type ) {
     6195                case 'email':
     6196                        $anonymous = 'deleted@site.invalid';
     6197                        break;
     6198                case 'url':
     6199                        $anonymous = 'https://site.invalid';
     6200                        break;
     6201                case 'ip':
     6202                        $anonymous = wp_privacy_anonymize_ip( $data );
     6203                        break;
     6204                case 'date':
     6205                        $anonymous = '0000-00-00 00:00:00';
     6206                        break;
     6207                case 'text':
     6208                        /* translators: deleted text */
     6209                        $anonymous = __( '[deleted]' );
     6210                        break;
     6211                case 'longtext':
     6212                        /* translators: deleted long text */
     6213                        $anonymous = __( 'This content was deleted by the author.' );
     6214                        break;
     6215                default:
     6216                        $anonymous = '';
     6217        }
     6218
     6219        /**
     6220         * Filters the anonymous data for each type.
     6221         *
     6222         * @since 5.0.0
     6223         *
     6224         * @param string $anonymous Anonymized data.
     6225         * @param string $data      Original data.
     6226         * @param string $type      Type of the data.
     6227         */
     6228        return apply_filters( 'wp_privacy_anonymize_data', $anonymous, $data, $type );
     6229}
  • tests/phpunit/tests/functions/anonymization.php

     
     1<?php
     2
     3/**
     4 * @group functions.php
     5 * @group privacy
     6 */
     7class Tests_Functions_Anonymization extends WP_UnitTestCase {
     8  function test_anonymize_invalid_ip() {
     9    $ip_addrs = array( '', 'invalid', '0.0.0.0.0' );
     10
     11    foreach ( (array) $ip_addrs as $ip_addr ) {
     12      $this->assertEquals( '0.0.0.0', wp_privacy_anonymize_data( $ip_addr, 'ip' ) );
     13    }
     14  }
     15
     16  function test_anonymize_ipv4() {
     17    $ip_addrs = array(
     18      '198.143.164.252' => '198.143.164.0',
     19      '127.0.0.1'       => '127.0.0.0',
     20    );
     21
     22    foreach ( (array) $ip_addrs as $ip_addr => $anonymized_ip_addr ) {
     23      $this->assertEquals( $anonymized_ip_addr, wp_privacy_anonymize_data( $ip_addr, 'ip' ) );
     24    }
     25  }
     26
     27  function test_anonymize_ipv6() {
     28    $ip_addrs = array(
     29      '2001:0db8:0a0b:12f0:0000:0000:0000:0001' => '2001:db8:a0b:12f0::',
     30      '2001:db8:a0b:12f0::1'                    => '2001:db8:a0b:12f0::',
     31      '2001:db8::1'                             => '2001:db8::',
     32      '::ffff:10.0.0.3'                         => '::ffff:10.0.0.0',
     33      '[2001:db8:a0b:12f0::1]'                  => '2001:db8:a0b:12f0::',
     34      '[2001:db8:a0b:12f0::1]:21'               => '2001:db8:a0b:12f0::',
     35      '::1'                                     => '::',
     36    );
     37
     38    foreach ( (array) $ip_addrs as $ip_addr => $anonymized_ip_addr ) {
     39      $this->assertEquals( $anonymized_ip_addr, wp_privacy_anonymize_data( $ip_addr, 'ip' ) );
     40    }
     41  }
     42
     43  function test_anonymize_email() {
     44    $this->assertEquals( 'deleted@site.invalid', wp_privacy_anonymize_data( 'bar@example.com', 'email' ) );
     45  }
     46
     47  function test_anonymize_url() {
     48    $this->assertEquals( 'https://site.invalid', wp_privacy_anonymize_data( 'https://example.com/author/username', 'url' ) );
     49  }
     50
     51  function test_anonymize_date() {
     52    $this->assertEquals( '0000-00-00 00:00:00', wp_privacy_anonymize_data( '2003-12-25 12:34:56', 'date' ) );
     53  }
     54
     55  function test_anonymize_text() {
     56    $text = __( 'Four score and seven years ago' );
     57    $this->assertNotEquals( $text, wp_privacy_anonymize_data( $text, 'text' ) );
     58  }
     59
     60  function test_anonymize_long_text() {
     61    $text = __( 'Four score and seven years ago' );
     62    $this->assertNotEquals( $text, wp_privacy_anonymize_data( $text, 'longtext' ) );
     63  }
     64}