Opened 2 years ago
Last modified 11 months ago
#59425 new defect (bug)
REST API: Preserve boolean values when generating next/prev Link headers
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Awaiting Review | Priority: | normal |
| Severity: | normal | Version: | 5.2 |
| Component: | REST API | Keywords: | |
| Focuses: | rest-api | Cc: |
Description
When generating rel="next" and rel="prev" values for the Link header in the terms, users, search, revisions, posts, global styles, and comments controllers, existing parameter data is passed to urlencode_deep(), which converts boolean false to an empty string.
The example I'm focused on is a request for terms with hide_empty set to false.
An initial URL like:
https://example.org/wp-json/wp/v2/tags?hide_empty=false&per_page=100&context=edit&_locale=user
Returns a response with a Link header of:
<https://example.org/wp-json/wp/v2/tags?hide_empty&per_page=100&context=edit&_locale=user&page=2>; rel="next"
When this URL is followed, a 400 response is returned from the REST API with the error: is not of type boolean.
When hide_empty=true is passed with the URL instead, the REST API converts the parameter to 1 in the Link header, which it then seems to accept in future requests as if it was boolean.
The cause of this is the use of urlencode_deep() on request params when generating the header:
$base = add_query_arg( urlencode_deep( $request_params ), $collection_url );
wp> urlencode_deep( true ); => string(1) "1" wp> urlencode_deep( false ); => string(0) "" // which is really wp> map_deep( true, 'urlencode' ); => string(1) "1" wp> map_deep( false, 'urlencode' ); => string(0) ""
Which is really just urlencode() making sure it's dealing with a string, as expected.
I _think_ the answer is for the REST API to restore boolean values in the request params back to URL-compatible strings before building the Link header. While false being altered breaks things, it is also strange that true is altered as well.
I set the version as 5.2, as this is when the urlencode_deep() change was made. (See [45267] via #46199) I haven't investigated further, but before that change, hide_empty would just be dropped from the rel="next" link entirely.
The same bug has been reported on the Gutenberg repo - https://github.com/WordPress/gutenberg/issues/67556.