diff --git a/wp-includes/rest-api.php b/wp-includes/rest-api.php index d59f570c02..8e48f892f7 100644 --- a/wp-includes/rest-api.php +++ b/wp-includes/rest-api.php @@ -998,6 +998,9 @@ function rest_validate_value_from_schema( $value, $args, $param = '' ) { if ( ! is_array( $value ) ) { $value = preg_split( '/[\s,]+/', $value ); } + if ( ! wp_is_numeric_array( $value ) ) { + return new WP_Error( 'rest_invalid_param', sprintf( /* translators: 1: parameter, 2: type name */ __( '%1$s is not of type %2$s.' ), $param, 'array' ) ); + } foreach ( $value as $index => $v ) { $is_valid = rest_validate_value_from_schema( $v, $args['items'], $param . '[' . $index . ']' ); if ( is_wp_error( $is_valid ) ) { @@ -1107,6 +1110,9 @@ function rest_sanitize_value_from_schema( $value, $args ) { foreach ( $value as $index => $v ) { $value[ $index ] = rest_sanitize_value_from_schema( $v, $args['items'] ); } + // Normalize to numeric array so nothing unexpected + // is in the keys. + $value = array_values( $value ); return $value; } if ( 'integer' === $args['type'] ) { @@ -1140,5 +1146,9 @@ function rest_sanitize_value_from_schema( $value, $args ) { } } + if ( 'string' === $args['type'] ) { + return strval( $value ); + } + return $value; } diff --git a/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php b/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php index e48a307a51..c4200a68d2 100644 --- a/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php +++ b/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php @@ -84,7 +84,7 @@ abstract class WP_REST_Meta_Fields { $response[ $name ] = $value; } - return (object) $response; + return $response; } /** @@ -133,10 +133,24 @@ abstract class WP_REST_Meta_Fields { */ if ( is_null( $request[ $name ] ) ) { $result = $this->delete_meta_value( $object_id, $name ); - } elseif ( $args['single'] ) { - $result = $this->update_meta_value( $object_id, $name, $request[ $name ] ); + if ( is_wp_error( $result ) ) { + return $result; + } + continue; + } + + $is_valid = rest_validate_value_from_schema( $request[ $name ], $args['schema'], 'meta.' . $name ); + if ( is_wp_error( $is_valid ) ) { + $is_valid->add_data( array( 'status' => 400 ) ); + return $is_valid; + } + + $value = rest_sanitize_value_from_schema( $request[ $name ], $args['schema'] ); + + if ( $args['single'] ) { + $result = $this->update_meta_value( $object_id, $name, $value ); } else { - $result = $this->update_multi_meta_value( $object_id, $name, $request[ $name ] ); + $result = $this->update_multi_meta_value( $object_id, $name, $value ); } if ( is_wp_error( $result ) ) { @@ -319,12 +333,13 @@ abstract class WP_REST_Meta_Fields { $default_args = array( 'name' => $name, 'single' => $args['single'], + 'type' => ! empty( $args['type'] ) ? $args['type'] : null, 'schema' => array(), 'prepare_callback' => array( $this, 'prepare_value' ), ); $default_schema = array( - 'type' => null, + 'type' => $default_args['type'], 'description' => empty( $args['description'] ) ? '' : $args['description'], 'default' => isset( $args['default'] ) ? $args['default'] : null, ); @@ -332,20 +347,18 @@ abstract class WP_REST_Meta_Fields { $rest_args = array_merge( $default_args, $rest_args ); $rest_args['schema'] = array_merge( $default_schema, $rest_args['schema'] ); - if ( empty( $rest_args['schema']['type'] ) ) { - // Skip over meta fields that don't have a defined type. - if ( empty( $args['type'] ) ) { - continue; - } + $type = ! empty( $rest_args['type'] ) ? $rest_args['type'] : null; + $type = ! empty( $rest_args['schema']['type'] ) ? $rest_args['schema']['type'] : $type; - if ( $rest_args['single'] ) { - $rest_args['schema']['type'] = $args['type']; - } else { - $rest_args['schema']['type'] = 'array'; - $rest_args['schema']['items'] = array( - 'type' => $args['type'], - ); - } + if ( ! in_array( $type, array( 'string', 'boolean', 'integer', 'number' ) ) ) { + continue; + } + + if ( empty( $rest_args['single'] ) ) { + $rest_args['schema']['items'] = array( + 'type' => $rest_args['type'], + ); + $rest_args['schema']['type'] = 'array'; } $registered[ $rest_args['name'] ] = $rest_args; diff --git a/wp-includes/version.php b/wp-includes/version.php index cf79be638f..8a8747bde7 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -4,7 +4,7 @@ * * @global string $wp_version */ -$wp_version = '4.7-beta3-39221'; +$wp_version = '4.7-beta3-39222'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.