WordPress.org

Make WordPress Core

Opened 4 months ago

Closed 4 months ago

Last modified 3 weeks ago

#52932 closed defect (bug) (fixed)

Rest Api enum validation does not work correctly WordPress 5.7

Reported by: stefanjoebstl Owned by: yakimun
Milestone: 5.7.1 Priority: normal
Severity: normal Version: 5.7
Component: REST API Keywords: has-patch has-unit-tests commit fixed-major
Focuses: rest-api Cc:

Description

The following code produces an error when sending a json request with 1, 2 or 3. If I don't use the enum validation it works fine...

<?php
  register_rest_route($this->namespace, '/someendpoint', array(
    array(
      'methods' => WP_REST_Server::CREATABLE,
      'callback' => array($this, 'createEndpoint'),
      'args' => array(
        'gender' => array(
          'type' => 'number',
          'enum' => array(
            1,
            2,
            3,
          ), 
        ),
      ),
    ),
));

The error says: gender isn't one of 1, 2 or 3.

Kind regards
Stefan

Change History (13)

#1 @SergeyBiryukov
4 months ago

  • Milestone changed from Awaiting Review to 5.7.1

Hi there, welcome to WordPress Trac! Thanks for the report.

Moving to 5.7.1 for investigation.

#2 @TimothyBlynJacobs
4 months ago

Thanks for the report @stefanjoebstl.

The issue here is that you are using a number type with integer values for the enum cases. This causes the incoming value to be sanitized to 1.0. The results are then compared strictly and 1.0 === 1 will fail in PHP.

You can fix this by specifying your type as an integer.

I think, though, we should allow a number with a zero fractional part to be equivalent to an integer of the same value. @yakimun do you have any thoughts on this?

See #51911.

#3 @stefanjoebstl
4 months ago

Thanks for the really fast answer @TimothyBlynJacobs ,

with integer it works as expected. But maybe you should consider the number with zero fractional part to work again, because in earlier versions it also worked if I used the number with the integer enum.

#4 @TimothyBlynJacobs
4 months ago

Yep, definitely. To clarify what changed, previously a strict comparison was also used, but the incoming value wasn't sanitized before checking that the enum value matched.

#5 @yakimun
4 months ago

@TimothyBlynJacobs Hi!

I think that it would be correct to consider such values equal.

Some test cases from the official "JSON Schema Test Suite" confirm this.
Example: https://github.com/json-schema-org/JSON-Schema-Test-Suite/blob/master/tests/draft2020-12/enum.json#L215

I can fix it if you don't mind.

#6 @TimothyBlynJacobs
4 months ago

  • Owner set to yakimun
  • Status changed from new to assigned

That'd be great, thanks @yakimun!

This ticket was mentioned in PR #1135 on WordPress/wordpress-develop by yakimun.


4 months ago

  • Keywords has-patch has-unit-tests added; needs-patch removed

With this fix, if rest_are_values_equal compares two values of type int or float (in any combination), we first cast both of them to float and then compare.

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

#8 @rachelbaker
4 months ago

  • Keywords commit added

The patch provided looks solid to me. Marking it for commit for 5.7.1.

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


4 months ago

#10 @SergeyBiryukov
4 months ago

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

In 50653:

REST API: Correct enum validation for numeric values.

When validating enum values as integer or number, consider a number with a zero fractional part to be equivalent to an integer of the same value.

In rest_are_values_equal(), when comparing two values of type int or float (in any combination), first cast both of them to float and then compare.

This matches some test cases from the official JSON Schema test suite.

Follow-up to [50010].

Props yakimun, stefanjoebstl, TimothyBlynJacobs, rachelbaker.
Fixes #52932.

#11 @SergeyBiryukov
4 months ago

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

Reopening for backporting to the 5.7 branch.

#12 @SergeyBiryukov
4 months ago

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

In 50656:

REST API: Correct enum validation for numeric values.

When validating enum values as integer or number, consider a number with a zero fractional part to be equivalent to an integer of the same value.

In rest_are_values_equal(), when comparing two values of type int or float (in any combination), first cast both of them to float and then compare.

This matches some test cases from the official JSON Schema test suite.

Follow-up to [50010].

Props yakimun, stefanjoebstl, TimothyBlynJacobs, rachelbaker.
Merges [50653] to the 5.7 branch.
Fixes #52932.

Note: See TracTickets for help on using tickets.