From 7b4f4be327c77b0be0fa27c1fae51812cc048a69 Mon Sep 17 00:00:00 2001 From: Rachel Baker Date: Tue, 27 Dec 2016 17:48:10 +0000 Subject: [PATCH] REST API: Allow schema sanitization_callback to be set to null to bypass fallback sanitization functions. The logic in WP_REST_Request->sanitize_params() added in [39091] did not account for `null` or `false` being the sanitization_callback preventing overriding `rest_parse_request_arg()`. This fixes that oversight, allowing the built in sanitization function to be bypassed. See #38593. Merges [39563] to the 4.7 branch. Props kkoppenhaver, rachelbaker, jnylen0. Fixes #39042. git-svn-id: https://develop.svn.wordpress.org/branches/4.7@39642 602fd350-edb4-49c9-b593-d223f7449a82 --- .../rest-api/class-wp-rest-request.php | 18 ++++++---- tests/phpunit/tests/rest-api/rest-request.php | 36 +++++++++++++++++++ 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/wp-includes/rest-api/class-wp-rest-request.php b/src/wp-includes/rest-api/class-wp-rest-request.php index 898f8658ed..4dd0dc2090 100644 --- a/src/wp-includes/rest-api/class-wp-rest-request.php +++ b/src/wp-includes/rest-api/class-wp-rest-request.php @@ -823,17 +823,21 @@ class WP_REST_Request implements ArrayAccess { continue; } foreach ( $this->params[ $type ] as $key => $value ) { - // if no sanitize_callback was specified, default to rest_parse_request_arg - // if a type was specified in the args. - if ( ! isset( $attributes['args'][ $key ]['sanitize_callback'] ) && ! empty( $attributes['args'][ $key ]['type'] ) ) { - $attributes['args'][ $key ]['sanitize_callback'] = 'rest_parse_request_arg'; + if ( ! isset( $attributes['args'][ $key ] ) ) { + continue; } - // Check if this param has a sanitize_callback added. - if ( ! isset( $attributes['args'][ $key ] ) || empty( $attributes['args'][ $key ]['sanitize_callback'] ) ) { + $param_args = $attributes['args'][ $key ]; + + // If the arg has a type but no sanitize_callback attribute, default to rest_parse_request_arg. + if ( ! array_key_exists( 'sanitize_callback', $param_args ) && ! empty( $param_args['type'] ) ) { + $param_args['sanitize_callback'] = 'rest_parse_request_arg'; + } + // If there's still no sanitize_callback, nothing to do here. + if ( empty( $param_args['sanitize_callback'] ) ) { continue; } - $sanitized_value = call_user_func( $attributes['args'][ $key ]['sanitize_callback'], $value, $this, $key ); + $sanitized_value = call_user_func( $param_args['sanitize_callback'], $value, $this, $key ); if ( is_wp_error( $sanitized_value ) ) { $invalid_params[ $key ] = $sanitized_value->get_error_message(); diff --git a/tests/phpunit/tests/rest-api/rest-request.php b/tests/phpunit/tests/rest-api/rest-request.php index 777a4d0bd1..7953f65bad 100644 --- a/tests/phpunit/tests/rest-api/rest-request.php +++ b/tests/phpunit/tests/rest-api/rest-request.php @@ -344,6 +344,42 @@ class Tests_REST_Request extends WP_UnitTestCase { $this->assertEquals( 'rest_invalid_param', $valid->get_error_code() ); } + public function test_sanitize_params_with_null_callback() { + $this->request->set_url_params( array( + 'some_email' => '', + ) ); + + $this->request->set_attributes( array( + 'args' => array( + 'some_email' => array( + 'type' => 'string', + 'format' => 'email', + 'sanitize_callback' => null, + ), + ), + ) ); + + $this->assertTrue( $this->request->sanitize_params() ); + } + + public function test_sanitize_params_with_false_callback() { + $this->request->set_url_params( array( + 'some_uri' => 1.23422, + ) ); + + $this->request->set_attributes( array( + 'args' => array( + 'some_uri' => array( + 'type' => 'string', + 'format' => 'uri', + 'sanitize_callback' => false, + ), + ), + ) ); + + $this->assertTrue( $this->request->sanitize_params() ); + } + public function test_has_valid_params_required_flag() { $this->request->set_attributes( array( 'args' => array(