Skip to content

Commit f53a87e

Browse files
committed
REST API: Fix object/array validation for JSON-encoded GET parameters.This commit aligns GET parameter handling with POST requests by allowingJSON-encoded strings to pass 'object' and 'array' validation andsanitization.- Added JSON coercion in rest_validate_value_from_schema().- Added JSON coercion in rest_sanitize_value_from_schema().- Supports multi-type schemas and uses json_last_error() for safety.Fixes #64926
1 parent 4d3b0b9 commit f53a87e

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

src/wp-includes/rest-api.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2182,6 +2182,7 @@ function rest_get_allowed_schema_keywords() {
21822182
* @return true|WP_Error
21832183
*/
21842184
function rest_validate_value_from_schema( $value, $args, $param = '' ) {
2185+
21852186
if ( isset( $args['anyOf'] ) ) {
21862187
$matching_schema = rest_find_any_matching_schema( $value, $args, $param );
21872188
if ( is_wp_error( $matching_schema ) ) {
@@ -2243,9 +2244,27 @@ function rest_validate_value_from_schema( $value, $args, $param = '' ) {
22432244
$is_valid = rest_validate_boolean_value_from_schema( $value, $param );
22442245
break;
22452246
case 'object':
2247+
if ( is_string( $value ) ) {
2248+
$trimmed_value = trim( $value );
2249+
if ( str_starts_with( $trimmed_value, '{' ) ) {
2250+
$decoded = json_decode( $value, true );
2251+
if ( json_last_error() === JSON_ERROR_NONE ) {
2252+
$value = $decoded;
2253+
}
2254+
}
2255+
}
22462256
$is_valid = rest_validate_object_value_from_schema( $value, $args, $param );
22472257
break;
22482258
case 'array':
2259+
if ( is_string( $value ) ) {
2260+
$trimmed_value = trim( $value );
2261+
if ( str_starts_with( $trimmed_value, '[' ) ) {
2262+
$decoded = json_decode( $value, true );
2263+
if ( json_last_error() === JSON_ERROR_NONE ) {
2264+
$value = $decoded;
2265+
}
2266+
}
2267+
}
22492268
$is_valid = rest_validate_array_value_from_schema( $value, $args, $param );
22502269
break;
22512270
case 'number':
@@ -2780,6 +2799,7 @@ function rest_validate_integer_value_from_schema( $value, $args, $param ) {
27802799
* @return mixed|WP_Error The sanitized value or a WP_Error instance if the value cannot be safely sanitized.
27812800
*/
27822801
function rest_sanitize_value_from_schema( $value, $args, $param = '' ) {
2802+
27832803
if ( isset( $args['anyOf'] ) ) {
27842804
$matching_schema = rest_find_any_matching_schema( $value, $args, $param );
27852805
if ( is_wp_error( $matching_schema ) ) {
@@ -2833,6 +2853,16 @@ function rest_sanitize_value_from_schema( $value, $args, $param = '' ) {
28332853
}
28342854

28352855
if ( 'array' === $args['type'] ) {
2856+
if ( is_string( $value ) ) {
2857+
$trimmed_value = trim( $value );
2858+
if ( str_starts_with( $trimmed_value, '[' ) ) {
2859+
$decoded = json_decode( $value, true );
2860+
if ( json_last_error() === JSON_ERROR_NONE ) {
2861+
$value = $decoded;
2862+
}
2863+
}
2864+
}
2865+
28362866
$value = rest_sanitize_array( $value );
28372867

28382868
if ( ! empty( $args['items'] ) ) {
@@ -2850,6 +2880,16 @@ function rest_sanitize_value_from_schema( $value, $args, $param = '' ) {
28502880
}
28512881

28522882
if ( 'object' === $args['type'] ) {
2883+
if ( is_string( $value ) ) {
2884+
$trimmed_value = trim( $value );
2885+
if ( str_starts_with( $trimmed_value, '{' ) ) {
2886+
$decoded = json_decode( $value, true );
2887+
if ( json_last_error() === JSON_ERROR_NONE ) {
2888+
$value = $decoded;
2889+
}
2890+
}
2891+
}
2892+
28532893
$value = rest_sanitize_object( $value );
28542894

28552895
foreach ( $value as $property => $v ) {

0 commit comments

Comments
 (0)