[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