From 86cbde382a0d323480a14b53c86f274599880ee2 Mon Sep 17 00:00:00 2001 From: Timothy Jacobs Date: Mon, 27 Apr 2020 02:27:02 +0000 Subject: [PATCH] REST API: Support the (min|max)Length JSON Schema keywords. Props sorenbronsted. Fixes #48820. git-svn-id: https://develop.svn.wordpress.org/trunk@47627 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/rest-api.php | 32 +++++++++++-- .../tests/rest-api/rest-schema-validation.php | 48 +++++++++++++++++++ 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php index d807b15720..64d42cf0c0 100644 --- a/src/wp-includes/rest-api.php +++ b/src/wp-includes/rest-api.php @@ -1337,9 +1337,35 @@ function rest_validate_value_from_schema( $value, $args, $param = '' ) { return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'boolean' ) ); } - if ( 'string' === $args['type'] && ! is_string( $value ) ) { - /* translators: 1: Parameter, 2: Type name. */ - return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'string' ) ); + if ( 'string' === $args['type'] ) { + if ( ! is_string( $value ) ) { + /* translators: 1: Parameter, 2: Type name. */ + return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not of type %2$s.' ), $param, 'string' ) ); + } + + if ( isset( $args['minLength'] ) && mb_strlen( $value ) < $args['minLength'] ) { + return new WP_Error( + 'rest_invalid_param', + sprintf( + /* translators: 1: Parameter, 2: Number of characters. */ + _n( '%1$s must be at least %2$s character long.', '%1$s must be at least %2$s characters long.', $args['minLength'] ), + $param, + number_format_i18n( $args['minLength'] ) + ) + ); + } + + if ( isset( $args['maxLength'] ) && mb_strlen( $value ) > $args['maxLength'] ) { + return new WP_Error( + 'rest_invalid_param', + sprintf( + /* translators: 1: Parameter, 2: Number of characters. */ + _n( '%1$s must be at most %2$s character long.', '%1$s must be at most %2$s characters long.', $args['maxLength'] ), + $param, + number_format_i18n( $args['maxLength'] ) + ) + ); + } } if ( isset( $args['format'] ) ) { diff --git a/tests/phpunit/tests/rest-api/rest-schema-validation.php b/tests/phpunit/tests/rest-api/rest-schema-validation.php index dd338f5068..d9d2bca7b6 100644 --- a/tests/phpunit/tests/rest-api/rest-schema-validation.php +++ b/tests/phpunit/tests/rest-api/rest-schema-validation.php @@ -348,4 +348,52 @@ class WP_Test_REST_Schema_Validation extends WP_UnitTestCase { $this->assertTrue( rest_validate_value_from_schema( array( 'raw' => 'My Value' ), $schema ) ); $this->assertWPError( rest_validate_value_from_schema( array( 'raw' => array( 'a list' ) ), $schema ) ); } + + /** + * @ticket 48820 + */ + public function test_string_min_length() { + $schema = array( + 'type' => 'string', + 'minLength' => 2, + ); + + // longer + $this->assertTrue( rest_validate_value_from_schema( 'foo', $schema ) ); + // exact + $this->assertTrue( rest_validate_value_from_schema( 'fo', $schema ) ); + // non-strings does not validate + $this->assertWPError( rest_validate_value_from_schema( 1, $schema ) ); + // to short + $this->assertWPError( rest_validate_value_from_schema( 'f', $schema ) ); + // one supplementary Unicode code point is not long enough + $mb_char = mb_convert_encoding( 'က', 'UTF-8', 'HTML-ENTITIES' ); + $this->assertWPError( rest_validate_value_from_schema( $mb_char, $schema ) ); + // two supplementary Unicode code point is long enough + $this->assertTrue( rest_validate_value_from_schema( $mb_char . $mb_char, $schema ) ); + } + + /** + * @ticket 48820 + */ + public function test_string_max_length() { + $schema = array( + 'type' => 'string', + 'maxLength' => 2, + ); + + // shorter + $this->assertTrue( rest_validate_value_from_schema( 'f', $schema ) ); + // exact + $this->assertTrue( rest_validate_value_from_schema( 'fo', $schema ) ); + // to long + $this->assertWPError( rest_validate_value_from_schema( 'foo', $schema ) ); + // non string + $this->assertWPError( rest_validate_value_from_schema( 100, $schema ) ); + // two supplementary Unicode code point is long enough + $mb_char = mb_convert_encoding( 'က', 'UTF-8', 'HTML-ENTITIES' ); + $this->assertTrue( rest_validate_value_from_schema( $mb_char, $schema ) ); + // three supplementary Unicode code point is to long + $this->assertWPError( rest_validate_value_from_schema( $mb_char . $mb_char . $mb_char, $schema ) ); + } }