[wp-trac] [WordPress Trac] #42961: REST API: Cannot pass empty object url encoded data (was: Rest API doesnt handle empty arrays in querystring correctly)

WordPress Trac noreply at wordpress.org
Sun Dec 1 21:39:35 UTC 2019


#42961: REST API: Cannot pass empty object url encoded data
--------------------------------------------------+-----------------------
 Reporter:  steffanhalv                           |       Owner:  (none)
     Type:  defect (bug)                          |      Status:  new
 Priority:  normal                                |   Milestone:  5.4
Component:  REST API                              |     Version:  4.7
 Severity:  normal                                |  Resolution:
 Keywords:  has-patch has-unit-tests 2nd-opinion  |     Focuses:  rest-api
--------------------------------------------------+-----------------------
Changes (by TimothyBlynJacobs):

 * keywords:  reporter-feedback => has-patch has-unit-tests 2nd-opinion
 * focuses:  rest-api, coding-standards => rest-api
 * milestone:  Awaiting Review => 5.4


Comment:

 Thanks for providing that context @steffanhalv! A couple of things to
 untangle here.

 The REST API does send CORS headers. As far as I know, the intention is
 that any WordPress with the REST API enabled would be able to accept JSON
 by default: https://github.com/WordPress/wordpress-
 develop/blob/bf3295d10f066ef6bf670bb272aae9db400e8be5/src/wp-includes
 /rest-api/class-wp-rest-server.php#L239 Is there a specific deficiency you
 noticed in the CORS setup that WordPress Core could address?

 If you were not aware, the REST API accepts form url encoded data as post
 data.

 For the actual issue, I'm not able to replicate if the schema is setup
 properly. Given the following REST API route:

 {{{#!php
 <?php
 add_action( 'rest_api_init', function () {
         register_rest_route(
                 'my-ns',
                 'my-route',
                 [
                         'methods'  => WP_REST_Server::EDITABLE,
                         'args'     => [
                                 'array' => [
                                         'type'              => 'array',
                                         'items'             => array(
                                                 'type' => 'string',
                                         ),
                                         'validate_callback' =>
 'rest_validate_request_arg',
                                         'sanitize_callback' =>
 'rest_sanitize_request_arg',
                                 ],
                         ],
                         'callback' => function ( WP_REST_Request $request
 ) {
                                 return new WP_REST_Response(
 $request->get_params() );
                         },
                 ]
         );
 } );
 }}}
 And the given request:
 {{{
 curl --request POST \
   --url http://trunk.test/wp-json/my-ns/my-route \
   --header 'accept: application/json' \
   --header 'content-type: application/x-www-form-urlencoded' \
   --data array=
 }}}

 I receive the following response:

 {{{
 {
   "array": []
 }
 }}}

 If there is not items schema set, then `rest_sanitize_value_from_schema()`
 will bail by just casting the value to an array and you'll get an array of
 a single string.

 Taking a look at your error message, though, it looks like you are trying
 to set an empty ''object'' not an ''array''. Doing a bit of research, it
 doesn't look like there is an RFC about how this should work, if anyone
 knows of one, please mention it. Languages also aren't consistent about
 it. For example, in nodejs.

 {{{
 > const qs = require( 'querystring' );
 > qs.stringify( { obj: {} } );
 'obj='
 > qs.parse( 'obj=' );
 { obj: '' }
 }}}

 In the REST API currently, `obj=` fails because it is not an object. And
 given that you can create an empty array with `arr=`. I think we can allow
 `obj=` as an empty object. There shouldn't be any BC concerns because that
 value is currently blocked by `rest_validate_value_from_schema`, so we
 wouldn't be transforming a previously valid value into a different value.
 `rest_sanitize_value_from_schema` will already convert anything invalid
 into an empty array so we should be good on that side as well.

 I've uploaded a patch that does that for review. I'm provisionally marking
 this for 5.4, but again this needs review before being committed.

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


More information about the wp-trac mailing list