WordPress.org

Make WordPress Core

Ticket #38818: 38818.1.diff

File 38818.1.diff, 7.4 KB (added by schlessera, 3 years ago)

Allow both IPv4 & IPv6 for comment author IP

  • src/wp-includes/rest-api.php

    commit f94dbc20e9a5a1335aebd78a055255007aabeddc
    Author: Alain Schlesser <alain.schlesser@gmail.com>
    Date:   Wed Nov 16 15:58:03 2016 +0100
    
        Accept both IPv4 and IPv6 addresses for comment author IP.
        
        - Add IPv4 & IPv6 versions of the `rest_is_ip_address()` function.
        - Provide validation routing for `ip`, `ipv4` and `ipv6`.
        - Validate `author_ip` against `ip` instead of `ipv4`
    
    diff --git src/wp-includes/rest-api.php src/wp-includes/rest-api.php
    index 255b8dc..411d275 100644
    function rest_parse_request_arg( $value, $request, $param ) { 
    869869}
    870870
    871871/**
    872  * Determines if a IPv4 address is valid.
     872 * Determines if an IP address is valid.
     873 *
     874 * Handles both IPv4 and IPv6 addresses.
     875 *
     876 * @since 4.7.0
    873877 *
    874  * Does not handle IPv6 addresses.
     878 * @param  string $ip IP address.
     879 * @return string|false The valid IP address, otherwise false.
     880 */
     881function rest_is_ip_address( $ip ) {
     882        return rest_is_ipv4_address( $ip ) || rest_is_ipv6_address( $ip );
     883}
     884
     885/**
     886 * Determines if a IPv4 address is valid.
    875887 *
    876888 * @since 4.7.0
    877889 *
    878890 * @param  string $ipv4 IP 32-bit address.
    879891 * @return string|false The valid IPv4 address, otherwise false.
    880892 */
    881 function rest_is_ip_address( $ipv4 ) {
    882         $pattern = '/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/';
    883 
    884         if ( ! preg_match( $pattern, $ipv4 ) ) {
    885                 return false;
    886         }
     893function rest_is_ipv4_address( $ipv4 ) {
     894        return filter_var( $ipv4, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 );
     895}
    887896
    888         return $ipv4;
     897/**
     898 * Determines if a IPv6 address is valid.
     899 *
     900 * @since 4.7.0
     901 *
     902 * @param  string $ipv6 IPv6 address.
     903 * @return string|false The valid IPv6 address, otherwise false.
     904 */
     905function rest_is_ipv6_address( $ipv6 ) {
     906        return filter_var( $ipv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 );
    889907}
    890908
    891909/**
    function rest_validate_value_from_schema( $value, $args, $param = '' ) { 
    10531071                                        return new WP_Error( 'rest_invalid_email', __( 'The email address you provided is invalid.' ) );
    10541072                                }
    10551073                                break;
    1056                         case 'ipv4' :
     1074                        case 'ip' :
    10571075                                if ( ! rest_is_ip_address( $value ) ) {
    1058                                         /* translators: %s: IP address */ 
     1076                                        /* translators: %s: IP address */
    10591077                                        return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not a valid IP address.' ), $value ) );
    10601078                                }
    10611079                                break;
     1080                        case 'ipv4' :
     1081                                if ( ! rest_is_ipv4_address( $value ) ) {
     1082                                        /* translators: %s: IP address */
     1083                                        return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not a valid IPv4 address.' ), $value ) );
     1084                                }
     1085                                break;
     1086                        case 'ipv6' :
     1087                                if ( ! rest_is_ipv6_address( $value ) ) {
     1088                                        /* translators: %s: IP address */
     1089                                        return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not a valid IPv6 address.' ), $value ) );
     1090                                }
     1091                                break;
    10621092                }
    10631093        }
    10641094
  • src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php

    diff --git src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php
    index 15e18f7..3a0ca0a 100644
    class WP_REST_Comments_Controller extends WP_REST_Controller { 
    11151115                                'author_ip'     => array(
    11161116                                        'description'  => __( 'IP address for the object author.' ),
    11171117                                        'type'         => 'string',
    1118                                         'format'       => 'ipv4',
     1118                                        'format'       => 'ip',
    11191119                                        'context'      => array( 'edit' ),
    11201120                                        'default'      => '127.0.0.1',
    11211121                                ),
  • tests/phpunit/tests/rest-api/rest-schema-validation.php

    diff --git tests/phpunit/tests/rest-api/rest-schema-validation.php tests/phpunit/tests/rest-api/rest-schema-validation.php
    index 4e4a111..982bb10 100644
    class WP_Test_REST_Schema_Validation extends WP_UnitTestCase { 
    8383                $this->assertWPError( rest_validate_value_from_schema( '2016-06-30', $schema ) );
    8484        }
    8585
     86        public function test_format_ip() {
     87                $schema = array(
     88                        'type'  => 'string',
     89                        'format' => 'ip',
     90                );
     91
     92                // IPv4.
     93                $this->assertTrue( rest_validate_value_from_schema( '127.0.0.1', $schema ) );
     94                $this->assertWPError( rest_validate_value_from_schema( '3333.3333.3333.3333', $schema ) );
     95                $this->assertWPError( rest_validate_value_from_schema( '1', $schema ) );
     96
     97                // IPv6.
     98                $this->assertTrue( rest_validate_value_from_schema( '::1', $schema ) ); // Loopback, compressed, non-routable.
     99                $this->assertTrue( rest_validate_value_from_schema( '::', $schema ) ); // Unspecified, compressed, non-routable.
     100                $this->assertTrue( rest_validate_value_from_schema( '0:0:0:0:0:0:0:1', $schema ) ); // Loopback, full.
     101                $this->assertTrue( rest_validate_value_from_schema( '0:0:0:0:0:0:0:0', $schema ) ); // Unspecified, full.
     102                $this->assertTrue( rest_validate_value_from_schema( '2001:DB8:0:0:8:800:200C:417A', $schema ) ); // Unicast, full.
     103                $this->assertTrue( rest_validate_value_from_schema( 'FF01:0:0:0:0:0:0:101', $schema ) ); // Multicast, full.
     104                $this->assertTrue( rest_validate_value_from_schema( '2001:DB8::8:800:200C:417A', $schema ) ); // Unicast, compressed.
     105                $this->assertTrue( rest_validate_value_from_schema( 'FF01::101', $schema ) ); // Multicast, compressed.
     106                $this->assertTrue( rest_validate_value_from_schema( 'fe80::217:f2ff:fe07:ed62', $schema ) );
     107                $this->assertWPError( rest_validate_value_from_schema( '', $schema ) ); // Empty string.
     108                $this->assertWPError( rest_validate_value_from_schema( '2001:DB8:0:0:8:800:200C:417A:221', $schema ) ); // Unicast, full.
     109                $this->assertWPError( rest_validate_value_from_schema( 'FF01::101::2', $schema ) ); // Multicast, compressed.
     110        }
     111
    86112        public function test_format_ipv4() {
    87113                $schema = array(
    88114                        'type'  => 'string',
    class WP_Test_REST_Schema_Validation extends WP_UnitTestCase { 
    93119                $this->assertWPError( rest_validate_value_from_schema( '1', $schema ) );
    94120        }
    95121
     122        public function test_format_ipv6() {
     123                $schema = array(
     124                        'type'  => 'string',
     125                        'format' => 'ipv6',
     126                );
     127                $this->assertTrue( rest_validate_value_from_schema( '::1', $schema ) ); // Loopback, compressed, non-routable.
     128                $this->assertTrue( rest_validate_value_from_schema( '::', $schema ) ); // Unspecified, compressed, non-routable.
     129                $this->assertTrue( rest_validate_value_from_schema( '0:0:0:0:0:0:0:1', $schema ) ); // Loopback, full.
     130                $this->assertTrue( rest_validate_value_from_schema( '0:0:0:0:0:0:0:0', $schema ) ); // Unspecified, full.
     131                $this->assertTrue( rest_validate_value_from_schema( '2001:DB8:0:0:8:800:200C:417A', $schema ) ); // Unicast, full.
     132                $this->assertTrue( rest_validate_value_from_schema( 'FF01:0:0:0:0:0:0:101', $schema ) ); // Multicast, full.
     133                $this->assertTrue( rest_validate_value_from_schema( '2001:DB8::8:800:200C:417A', $schema ) ); // Unicast, compressed.
     134                $this->assertTrue( rest_validate_value_from_schema( 'FF01::101', $schema ) ); // Multicast, compressed.
     135                $this->assertTrue( rest_validate_value_from_schema( 'fe80::217:f2ff:fe07:ed62', $schema ) );
     136                $this->assertWPError( rest_validate_value_from_schema( '', $schema ) ); // Empty string.
     137                $this->assertWPError( rest_validate_value_from_schema( '2001:DB8:0:0:8:800:200C:417A:221', $schema ) ); // Unicast, full.
     138                $this->assertWPError( rest_validate_value_from_schema( 'FF01::101::2', $schema ) ); // Multicast, compressed.
     139        }
     140
    96141        public function test_type_array() {
    97142                $schema = array(
    98143                        'type' => 'array',