Make WordPress Core

Opened 7 weeks ago

Last modified 44 hours ago

#62646 reopened defect (bug)

PHP Warning in REST API when post_type doesn't support post-formats, but a post-format filter is applied.

Reported by: dd32's profile dd32 Owned by: peterwilsoncc's profile peterwilsoncc
Milestone: 6.7.2 Priority: normal
Severity: normal Version: 6.7
Component: REST API Keywords: has-patch dev-feedback fixed-major
Focuses: Cc:

Description

In #62014 querying for post types via the ?format query parameter was added.

This has caused some PHP Warnings to be emitted when querying with an invalid post-format on a post_type that does not support post formats.

For example:

GET https://example.org/wp-json/wp/v2/pt-no-post-formats?format=json

E_WARNING: in_array() expects parameter 2 to be array, string given in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php:363
E_WARNING: array_map(): Expected parameter 2 to be an array, string given in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php:380

This is caused by the "pt-no-post-formats" post_type not supporting post-formats, and as such, not having the format query param added to the endpoints schema.
https://core.trac.wordpress.org/browser/trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php?rev=59453&marks=3050-3060#L3047

In itself, that's not a concern, but the logic in the endpoint then only checks to see if the format query parameter is present - not that the post_type supports it, and then treating it as an array (As the schema has validated that it is one)
https://core.trac.wordpress.org/browser/trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php?rev=59453&marks=349#L346

Change History (15)

#1 @dd32
7 weeks ago

One way to resolve this, one could check the post_type supports post-formats before adding it to the query:

  • wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

     
    346346
    347347                $args = $this->prepare_tax_query( $args, $request );
    348348
    349                 if ( ! empty( $request['format'] ) ) {
     349                if ( ! empty( $request['format'] ) && post_type_supports( $this->post_type, 'post-formats' ) ) {
    350350                        $formats = $request['format'];
    351351                        /*
    352352                         * The relation needs to be set to `OR` since the request can contain

However this causes a logic change between 6.7 and post-change;
Currently querying https://example.org/wp-json/wp/v2/pt-no-post-formats?format[]=standard will result in no-results (kinda expected, since no post-formats in that post type will match). after the change, it'll ignore the parameter and return the same results as https://example.org/wp-json/wp/v2/pt-no-post-formats.

I think that's likely expected, and would be the same as querying ?skajdghadisjvxkhadsijf=true (assuming that's not a valid query param).

(cc @peterwilsoncc this is what i mentioned to you)

#2 @dd32
7 weeks ago

#62645 was marked as a duplicate.

This ticket was mentioned in PR #7951 on WordPress/wordpress-develop by @yogeshbhutkar.


7 weeks ago
#3

  • Keywords has-patch added

### Description:
Implement a validation check to ensure the given post type supports post formats before serving the data through the REST API.

### Relevant Screenshots:
https://github.com/user-attachments/assets/cb463b3e-7861-463c-ac4d-5688676338f0

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

#4 @yogeshbhutkar
7 weeks ago

Hi @dd32, thank you for raising the ticket. I’ve taken a slightly different approach to address the issue. In cases where the post-formats feature itself is not supported, I believe it would be more effective to display an error message to the user, similar to the handling we have when the value provided in the formats parameter is not registered. This approach would help users identify the limitation more clearly, enabling them to update either the endpoint or the respective format support as needed, rather than encountering unexpected data. I’d appreciate hearing your thoughts on this approach.

#5 @dd32
7 weeks ago

  • Owner set to peterwilsoncc
  • Status changed from new to reviewing

Personally I'm not in love with the idea of returning an error here. It's not an error, it's an unknown query parameter.

upon reviewing the file, my diff took the wrong approach, the existing endpoint validation uses the list of registered input variables, updated change included below. Checking isset() is enough as it can't be an empty value.

  • wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

     
    346346
    347347                $args = $this->prepare_tax_query( $args, $request );
    348348
    349                 if ( ! empty( $request['format'] ) ) {
     349                if ( isset( $registered['format'], $request['format'] ) ) {
    350350                        $formats = $request['format'];
    351351                        /*
    352352                         * The relation needs to be set to `OR` since the request can contain

#6 @yogeshbhutkar
7 weeks ago

I've updated the PR to reflect on the suggested changes with a new commit.

However, I was wondering, if a Post Type supports post-formats and if we make a GET Request to it:

GET: http://localhost:8889/wp-json/wp/v2/no-post-formats?format[]=json

Then this would return an error stating rest_invalid_param. But if we incorporate the above logic and repeat the request, assuming that post-formats are now not supported for the Post Type, it will pass through and return an empty array. Seems expected that the param format would be ignored altogether, but sounds a little inconsistent maybe?

#7 @dd32
6 weeks ago

#62682 was marked as a duplicate.

#8 @dd32
6 weeks ago

As #62682 notes, this is actually a fatal in PHP8.

#9 @SergeyBiryukov
6 weeks ago

  • Milestone changed from Awaiting Review to 6.8

#10 @peterwilsoncc
6 weeks ago

  • Milestone changed from 6.8 to 6.7.2

As this was introduced during the 6.7 release cycle, I've moved it on to the minor release milestone for consideration.

This ticket was mentioned in Slack in #core by jorbin. View the logs.


5 weeks ago

#12 @peterwilsoncc
5 weeks ago

  • Resolution set to fixed
  • Status changed from reviewing to closed

In 59544:

REST API: Protect against fatal error for post types without format support.

Ignore the format parameter introduced in WordPress 6.7 for post types that do not support post formats. This protects against a fatal error being thrown in later version of PHP or a warning in earlier versions of PHP.

Follow up to r59115.

Props dd32, sergeybiryukov, yogeshbhutkar.
Fixes #62646.
See #62014.

#14 @peterwilsoncc
5 weeks ago

  • Keywords dev-feedback fixed-major added
  • Resolution fixed deleted
  • Status changed from closed to reopened

Reopening for backport consideration to the 6.7 branch upon another committers approval.

This ticket was mentioned in Slack in #core by jorbin. View the logs.


44 hours ago

Note: See TracTickets for help on using tickets.