Make WordPress Core

Opened 11 months ago

#59425 new defect (bug)

REST API: Preserve boolean values when generating next/prev Link headers

Reported by: jeremyfelt's profile jeremyfelt 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.

Change History (0)

Note: See TracTickets for help on using tickets.