REST API: Fix multi-type schemas with integer fields.

In [48306] support for multi-typed schemas was improved to first detect the data type of the value before applying further validation. The `integer` data type was detected using the new `rest_is_integer` function. This function used logic, however, that assumed that the value had already passed an `is_numeric` check. This meant that if `integer` and `string` were both acceptable types, the value would always be considered an `integer` causing the later accurate type validation to fail.

This commit fixes the `rest_is_integer` logic to include an `is_numeric` check.

Props rtagliento.
Fixes #51146.


git-svn-id: https://develop.svn.wordpress.org/trunk@48881 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Timothy Jacobs 2020-08-27 02:55:39 +00:00
parent c8b5610b91
commit 6c76a13139
3 changed files with 85 additions and 1 deletions

View File

@ -1315,7 +1315,7 @@ function rest_is_boolean( $maybe_bool ) {
* @return bool True if an integer, otherwise false.
*/
function rest_is_integer( $maybe_integer ) {
return round( floatval( $maybe_integer ) ) === floatval( $maybe_integer );
return is_numeric( $maybe_integer ) && round( floatval( $maybe_integer ) ) === floatval( $maybe_integer );
}
/**

View File

@ -1918,6 +1918,69 @@ class Tests_REST_API extends WP_UnitTestCase {
);
}
/**
* @ticket 51146
*
* @dataProvider _dp_rest_is_integer
*
* @param bool $expected Expected result of the check.
* @param mixed $value The value to check.
*/
public function test_rest_is_integer( $expected, $value ) {
$is_integer = rest_is_integer( $value );
if ( $expected ) {
$this->assertTrue( $is_integer );
} else {
$this->assertFalse( $is_integer );
}
}
public function _dp_rest_is_integer() {
return array(
array(
true,
1,
),
array(
true,
'1',
),
array(
true,
0,
),
array(
true,
-1,
),
array(
true,
'05',
),
array(
false,
'garbage',
),
array(
false,
5.5,
),
array(
false,
'5.5',
),
array(
false,
array(),
),
array(
false,
true,
),
);
}
/**
* @ticket 50300
*
@ -2018,6 +2081,11 @@ class Tests_REST_API extends WP_UnitTestCase {
'a,b',
array( 'array', 'string' ),
),
array(
'string',
'hello',
array( 'integer', 'string' ),
),
);
}
}

View File

@ -1040,4 +1040,20 @@ class WP_Test_REST_Schema_Validation extends WP_UnitTestCase {
$data[1] = array_reverse( $data[1] );
$this->assertTrue( rest_validate_value_from_schema( $data, $schema ) );
}
/**
* @ticket 50300
*/
public function test_string_or_integer() {
$schema = array(
'type' => array( 'integer', 'string' ),
);
$this->assertTrue( rest_validate_value_from_schema( 'garbage', $schema ) );
$this->assertTrue( rest_validate_value_from_schema( 15, $schema ) );
$this->assertTrue( rest_validate_value_from_schema( '15', $schema ) );
$this->assertTrue( rest_validate_value_from_schema( '15.5', $schema ) );
$this->assertWPError( rest_validate_value_from_schema( 15.5, $schema ) );
}
}