Make WordPress Core

Opened 10 months ago

Last modified 9 months ago

#60599 new defect (bug)

REST API: rest_filter_response_fields fails with a PHP fatal when a custom API endpoint returns a scalar value.

Reported by: xknown's profile xknown Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version:
Component: REST API Keywords: has-unit-tests
Focuses: Cc:

Description

The code in rest_filter_response_fields seems to only work with arrays. Thus if a given API endpoint returns a scalar value, then querying this endpoint by adding the _fields GET parameter will throw a PHP fatal in PHP >= 8.x.

Steps to reproduce it:
Add the following dummy plugin and enable it to a test WP

alex@wayra time % cat time.php
<?php

/**
 * Plugin Name: Datetime
 */

function my_awesome_func() {
	return date( 'c' );
}
add_action( 'rest_api_init', function () {
	register_rest_route( 'myplugin/v1', '/datetime', array(
		'methods' => 'GET',
		'callback' => 'my_awesome_func',
	) );
} );
{
	"plugins": [
		"."
	]
}

alex@wayra time % cat .wp-env.json
{
	"plugins": [
		"."
	]
}

alex@wayra time % wp-env start
WordPress development site started at http://localhost:8888/
WordPress test site started at http://localhost:8889/
MySQL is listening on port 32768
MySQL for automated testing is listening on port 32769

 ✔ Done! (in 77s 181ms)

alex@wayra time % curl 'http://localhost:8888/?rest_route=/myplugin/v1/datetime'
"2024-02-22T09:38:36+00:00"%


alex@wayra time % curl 'http://localhost:8888/?rest_route=/myplugin/v1/datetime&_fields=foo'

Fatal error: Uncaught TypeError: array_intersect_key(): Argument #1 ($array) must be of type array, string given in /var/www/html/wp-includes/rest-api.php:869
Stack trace:
#0 /var/www/html/wp-includes/rest-api.php(869): array_intersect_key('2024-02-22T09:3...', Array)
#1 /var/www/html/wp-includes/rest-api.php(928): _rest_array_intersect_key_recursive('2024-02-22T09:3...', Array)
#2 /var/www/html/wp-includes/class-wp-hook.php(324): rest_filter_response_fields(Object(WP_REST_Response), Object(WP_REST_Server), Object(WP_REST_Request))
#3 /var/www/html/wp-includes/plugin.php(205): WP_Hook->apply_filters(Object(WP_REST_Response), Array)
#4 /var/www/html/wp-includes/rest-api/class-wp-rest-server.php(454): apply_filters('rest_post_dispa...', Object(WP_REST_Response), Object(WP_REST_Server), Object(WP_REST_Request))
#5 /var/www/html/wp-includes/rest-api.php(424): WP_REST_Server->serve_request('/myplugin/v1/da...')
#6 /var/www/html/wp-includes/class-wp-hook.php(324): rest_api_loaded(Object(WP))
#7 /var/www/html/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters('', Array)
#8 /var/www/html/wp-includes/plugin.php(565): WP_Hook->do_action(Array)
#9 /var/www/html/wp-includes/class-wp.php(418): do_action_ref_array('parse_request', Array)
#10 /var/www/html/wp-includes/class-wp.php(813): WP->parse_request('')
#11 /var/www/html/wp-includes/functions.php(1336): WP->main('')
#12 /var/www/html/wp-blog-header.php(16): wp()
#13 /var/www/html/index.php(17): require('/var/www/html/w...')
#14 {main}
  thrown in /var/www/html/wp-includes/rest-api.php on line 869

Change History (4)

This ticket was mentioned in PR #6158 on WordPress/wordpress-develop by xknown.


10 months ago
#1

  • Keywords has-patch has-unit-tests added

rest_filter_response_fields() does not currently work if a given API endpoint returns an scalar value.

Trac ticket: https://core.trac.wordpress.org/ticket/60599

#2 @swissspidy
10 months ago

  • Keywords needs-patch added; has-patch removed
  • Milestone changed from Awaiting Review to Future Release

I was just about to say the REST API is not really designed for returning scalar data, but this is literally shown as an example in the documentation: https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/.

A fatal error is a poor experience for sure, so can't hurt to fix this.

#3 @xknown
10 months ago

Yes, I grabbed the example from that page :)

Anyway, the reason I reported this is because we noticed this problem while upgrading a WP site from PHP 7.4 to PHP 8.x.

#4 @xknown
9 months ago

  • Keywords needs-patch removed
Note: See TracTickets for help on using tickets.