[wp-trac] [WordPress Trac] #64926: REST API: GET requests fail object/array schema validation when params are JSON-serialized strings

WordPress Trac noreply at wordpress.org
Thu Apr 2 04:48:46 UTC 2026


#64926: REST API: GET requests fail object/array schema validation when params are
JSON-serialized strings
-------------------------+-------------------------------------------------
 Reporter:  dsmy         |       Owner:  (none)
     Type:  defect       |      Status:  new
  (bug)                  |
 Priority:  normal       |   Milestone:  Awaiting Review
Component:  REST API     |     Version:
 Severity:  normal       |  Resolution:
 Keywords:  has-patch    |     Focuses:  javascript, rest-api, php-
                         |  compatibility
-------------------------+-------------------------------------------------

Comment (by liaison):

 Replying to [comment:21 abcd95]:
 > IMO, placing the decode at the top of the function misses `anyOf/oneOf`
 schemas with no top-level type, and the $type resolves to `''` and the
 block is skipped on the initial call. It only works because recursive
 calls from rest_find_any_matching_schema() re-enter with the sub-schema's
 type set.
 >
 > Moving the decode inside the switch (validation) and before
 rest_sanitize_array()/rest_sanitize_object() (sanitization) ensures it
 fires after type resolution, regardless of schema.

 Thanks @abcd95. The assessment is correct. Moving the decoding logic after
 the type resolution ensures full compatibility with schemas that rely
 solely on anyOf or oneOf without a top-level type declaration.
 {{{#!php
 <?php
 function rest_sanitize_value_from_schema( $value, $args, $param = '' ) {
 ...
    if ( 'array' === $args['type'] ) {
         if ( is_string( $value ) ) {
             $trimmed_value = trim( $value );
             if ( str_starts_with( $trimmed_value, '[' ) ) {
                 $decoded = json_decode( $value, true );
                 if ( json_last_error() === JSON_ERROR_NONE ) {
                     $value = $decoded;
                 }
             }
         }

         $value = rest_sanitize_array( $value );

     ...
     }

     if ( 'object' === $args['type'] ) {
         if ( is_string( $value ) ) {
             $trimmed_value = trim( $value );
             if ( str_starts_with( $trimmed_value, '{' ) ) {
                 $decoded = json_decode( $value, true );
                 if ( json_last_error() === JSON_ERROR_NONE ) {
                     $value = $decoded;
                 }
             }
         }

         $value = rest_sanitize_object( $value );
         ....
     }
 ...
 }

 function rest_validate_value_from_schema( $value, $args, $param = '' ) {
 ...
                 case 'object':
                         if ( is_string( $value ) ) {
                                 $trimmed_value = trim( $value );
                                 if ( str_starts_with( $trimmed_value, '{'
 ) ) {
                                         $decoded = json_decode( $value,
 true );
                                         if ( json_last_error() ===
 JSON_ERROR_NONE ) {
                                                 $value = $decoded;
                                         }
                                 }
                         }
                         $is_valid =
 rest_validate_object_value_from_schema( $value, $args, $param );
                         break;
                 case 'array':
                         if ( is_string( $value ) ) {
                                 $trimmed_value = trim( $value );
                                 if ( str_starts_with( $trimmed_value, '['
 ) ) {
                                         $decoded = json_decode( $value,
 true );
                                         if ( json_last_error() ===
 JSON_ERROR_NONE ) {
                                                 $value = $decoded;
                                         }
                                 }
                         }
                         $is_valid = rest_validate_array_value_from_schema(
 $value, $args, $param );
                         break;
 ...
 }

 }}}

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/64926#comment:22>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list