mirror of
https://github.com/WordPress/WordPress.git
synced 2024-09-20 19:41:28 +02:00
REST API: Support type coercion when validating the enum
JSON Schema keyword.
Previously, the `enum` keyword was validated by perform a strict equality check. For `string` types this is generally ok, but it prevented using alternative types like `number` when rich type support isn't available. Now the same level of type coercion/sanitization is applied when validating `enum` as all other validation checks. This means that a value of `"1"` will be accepted for an `enum` of `[ 0, 1 ]`. Additionally, `object` types now properly ignore key order when checking for equality. Props yakimun. Fixes #51911. Built from https://develop.svn.wordpress.org/trunk@50010 git-svn-id: http://core.svn.wordpress.org/trunk@49711 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
db01832512
commit
1a65652cbc
@ -1874,6 +1874,73 @@ function rest_find_one_matching_schema( $value, $args, $param, $stop_after_first
|
|||||||
return $matching_schemas[0]['schema_object'];
|
return $matching_schemas[0]['schema_object'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the equality of two values, following JSON Schema semantics.
|
||||||
|
*
|
||||||
|
* Property order is ignored for objects.
|
||||||
|
*
|
||||||
|
* Values must have been previously sanitized/coerced to their native types.
|
||||||
|
*
|
||||||
|
* @since 5.7.0
|
||||||
|
*
|
||||||
|
* @param mixed $value1 The first value to check.
|
||||||
|
* @param mixed $value2 The second value to check.
|
||||||
|
* @return bool True if the values are equal or false otherwise.
|
||||||
|
*/
|
||||||
|
function rest_are_values_equal( $value1, $value2 ) {
|
||||||
|
if ( is_array( $value1 ) && is_array( $value2 ) ) {
|
||||||
|
if ( count( $value1 ) !== count( $value2 ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ( $value1 as $index => $value ) {
|
||||||
|
if ( ! array_key_exists( $index, $value2 ) || ! rest_are_values_equal( $value, $value2[ $index ] ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value1 === $value2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that the given value is a member of the JSON Schema "enum".
|
||||||
|
*
|
||||||
|
* @since 5.7.0
|
||||||
|
*
|
||||||
|
* @param mixed $value The value to validate.
|
||||||
|
* @param array $args The schema array to use.
|
||||||
|
* @param string $param The parameter name, used in error messages.
|
||||||
|
* @return true|WP_Error True if the "enum" contains the value or a WP_Error instance otherwise.
|
||||||
|
*/
|
||||||
|
function rest_validate_enum( $value, $args, $param ) {
|
||||||
|
$sanitized_value = rest_sanitize_value_from_schema( $value, $args, $param );
|
||||||
|
if ( is_wp_error( $sanitized_value ) ) {
|
||||||
|
return $sanitized_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ( $args['enum'] as $enum_value ) {
|
||||||
|
if ( rest_are_values_equal( $sanitized_value, $enum_value ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$encoded_enum_values = array();
|
||||||
|
foreach ( $args['enum'] as $enum_value ) {
|
||||||
|
$encoded_enum_values[] = is_scalar( $enum_value ) ? $enum_value : wp_json_encode( $enum_value );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( count( $encoded_enum_values ) === 1 ) {
|
||||||
|
/* translators: 1: Parameter, 2: Valid values. */
|
||||||
|
return new WP_Error( 'rest_not_in_enum', wp_sprintf( __( '%1$s is not %2$s.' ), $param, $encoded_enum_values[0] ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* translators: 1: Parameter, 2: List of valid values. */
|
||||||
|
return new WP_Error( 'rest_not_in_enum', wp_sprintf( __( '%1$s is not one of %2$l.' ), $param, $encoded_enum_values ) );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all valid JSON schema properties.
|
* Get all valid JSON schema properties.
|
||||||
*
|
*
|
||||||
@ -2153,13 +2220,6 @@ function rest_validate_value_from_schema( $value, $args, $param = '' ) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty( $args['enum'] ) ) {
|
|
||||||
if ( ! in_array( $value, $args['enum'], true ) ) {
|
|
||||||
/* translators: 1: Parameter, 2: List of valid values. */
|
|
||||||
return new WP_Error( 'rest_not_in_enum', sprintf( __( '%1$s is not one of %2$s.' ), $param, implode( ', ', $args['enum'] ) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( in_array( $args['type'], array( 'integer', 'number' ), true ) ) {
|
if ( in_array( $args['type'], array( 'integer', 'number' ), true ) ) {
|
||||||
if ( ! is_numeric( $value ) ) {
|
if ( ! is_numeric( $value ) ) {
|
||||||
return new WP_Error(
|
return new WP_Error(
|
||||||
@ -2234,6 +2294,13 @@ function rest_validate_value_from_schema( $value, $args, $param = '' ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! empty( $args['enum'] ) ) {
|
||||||
|
$enum_contains_value = rest_validate_enum( $value, $args, $param );
|
||||||
|
if ( is_wp_error( $enum_contains_value ) ) {
|
||||||
|
return $enum_contains_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The "format" keyword should only be applied to strings. However, for backward compatibility,
|
// The "format" keyword should only be applied to strings. However, for backward compatibility,
|
||||||
// we allow the "format" keyword if the type keyword was not specified, or was set to an invalid value.
|
// we allow the "format" keyword if the type keyword was not specified, or was set to an invalid value.
|
||||||
if ( isset( $args['format'] )
|
if ( isset( $args['format'] )
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
*
|
*
|
||||||
* @global string $wp_version
|
* @global string $wp_version
|
||||||
*/
|
*/
|
||||||
$wp_version = '5.7-alpha-50009';
|
$wp_version = '5.7-alpha-50010';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||||
|
Loading…
Reference in New Issue
Block a user