From 0e609fa717c6c0b33e2a6c77fa7069cd14a27c82 Mon Sep 17 00:00:00 2001 From: Joe Hoyle Date: Mon, 31 Oct 2016 17:07:14 +0000 Subject: [PATCH] REST API: Sanitize arrays being sent as CSVs. In #38586 the ability to parse arrays as csv was introduced, however it didn't add any support for validating csv arrays. This adds such sanitization, and also a good amount of unit tests for all sanitization baed off schema. See #38586. git-svn-id: https://develop.svn.wordpress.org/trunk@39061 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/rest-api.php | 3 + .../rest-api/rest-schema-sanitization.php | 89 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 tests/phpunit/tests/rest-api/rest-schema-sanitization.php diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php index 988dd9c778..8642460dd8 100644 --- a/src/wp-includes/rest-api.php +++ b/src/wp-includes/rest-api.php @@ -1097,6 +1097,9 @@ function rest_sanitize_value_from_schema( $value, $args ) { if ( empty( $args['items'] ) ) { return (array) $value; } + if ( ! is_array( $value ) ) { + $value = preg_split( '/[\s,]+/', $value ); + } foreach ( $value as $index => $v ) { $value[ $index ] = rest_sanitize_value_from_schema( $v, $args['items'] ); } diff --git a/tests/phpunit/tests/rest-api/rest-schema-sanitization.php b/tests/phpunit/tests/rest-api/rest-schema-sanitization.php new file mode 100644 index 0000000000..875a2aafc5 --- /dev/null +++ b/tests/phpunit/tests/rest-api/rest-schema-sanitization.php @@ -0,0 +1,89 @@ + 'number', + ); + $this->assertEquals( 1, rest_sanitize_value_from_schema( 1, $schema ) ); + $this->assertEquals( 1.10, rest_sanitize_value_from_schema( '1.10', $schema ) ); + $this->assertEquals( 1, rest_sanitize_value_from_schema( '1abc', $schema ) ); + $this->assertEquals( 0, rest_sanitize_value_from_schema( 'abc', $schema ) ); + $this->assertEquals( 0, rest_sanitize_value_from_schema( array(), $schema ) ); + } + + public function test_type_integer() { + $schema = array( + 'type' => 'integer', + ); + $this->assertEquals( 1, rest_sanitize_value_from_schema( 1, $schema ) ); + $this->assertEquals( 1, rest_sanitize_value_from_schema( '1.10', $schema ) ); + $this->assertEquals( 1, rest_sanitize_value_from_schema( '1abc', $schema ) ); + $this->assertEquals( 0, rest_sanitize_value_from_schema( 'abc', $schema ) ); + $this->assertEquals( 0, rest_sanitize_value_from_schema( array(), $schema ) ); + } + + public function test_type_string() { + $schema = array( + 'type' => 'string', + ); + $this->assertEquals( 'Hello', rest_sanitize_value_from_schema( 'Hello', $schema ) ); + $this->assertEquals( '1.10', rest_sanitize_value_from_schema( 1.10, $schema ) ); + $this->assertEquals( '1', rest_sanitize_value_from_schema( 1, $schema ) ); + } + + public function test_type_boolean() { + $schema = array( + 'type' => 'boolean', + ); + $this->assertEquals( true, rest_sanitize_value_from_schema( '1', $schema ) ); + $this->assertEquals( true, rest_sanitize_value_from_schema( 'true', $schema ) ); + $this->assertEquals( true, rest_sanitize_value_from_schema( '100', $schema ) ); + $this->assertEquals( true, rest_sanitize_value_from_schema( 1, $schema ) ); + $this->assertEquals( false, rest_sanitize_value_from_schema( '0', $schema ) ); + $this->assertEquals( false, rest_sanitize_value_from_schema( 'false', $schema ) ); + $this->assertEquals( false, rest_sanitize_value_from_schema( 0, $schema ) ); + } + + public function test_format_email() { + $schema = array( + 'type' => 'string', + 'format' => 'email', + ); + $this->assertEquals( 'email@example.com', rest_sanitize_value_from_schema( 'email@example.com', $schema ) ); + $this->assertEquals( 'a@b.c', rest_sanitize_value_from_schema( 'a@b.c', $schema ) ); + $this->assertEquals( 'invalid', rest_sanitize_value_from_schema( 'invalid', $schema ) ); + } + + public function test_type_array() { + $schema = array( + 'type' => 'array', + 'items' => array( + 'type' => 'number', + ), + ); + $this->assertEquals( array( 1 ), rest_sanitize_value_from_schema( array( 1 ), $schema ) ); + $this->assertEquals( array( 1 ), rest_sanitize_value_from_schema( array( '1' ), $schema ) ); + } + + public function test_type_array_as_csv() { + $schema = array( + 'type' => 'array', + 'items' => array( + 'type' => 'number', + ), + ); + $this->assertEquals( array( 1, 2 ), rest_sanitize_value_from_schema( '1,2', $schema ) ); + $this->assertEquals( array( 1, 2, 0 ), rest_sanitize_value_from_schema( '1,2,a', $schema ) ); + } +}