Skip to content

Commit 6a568e8

Browse files
committed
Code Modernization: Fix rest_convert_error_to_response() handling of non-array error data when obtaining status.
While the error data is normally an array, this is not guaranteed. This issue would have been detected by PHPStan rule level 9, since `WP_Error::get_all_error_data()` returns `mixed[]`. Developed in #11307 Follow-up to r61429. Props nateallen, desrosj, jorbin, mukesh27, westonruter. See #63430. Fixes #64901. git-svn-id: https://develop.svn.wordpress.org/trunk@62107 602fd350-edb4-49c9-b593-d223f7449a82
1 parent ad285ee commit 6a568e8

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

src/wp-includes/rest-api.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3427,8 +3427,15 @@ function rest_get_endpoint_args_for_schema( $schema, $method = WP_REST_Server::C
34273427
function rest_convert_error_to_response( $error ) {
34283428
$status = array_reduce(
34293429
$error->get_all_error_data(),
3430-
static function ( $status, $error_data ) {
3431-
return $error_data['status'] ?? $status;
3430+
/**
3431+
* @param int $status Status.
3432+
* @param mixed $error_data Error data.
3433+
*/
3434+
static function ( int $status, $error_data ): int {
3435+
if ( is_array( $error_data ) && isset( $error_data['status'] ) && is_numeric( $error_data['status'] ) ) {
3436+
$status = (int) $error_data['status'];
3437+
}
3438+
return $status;
34323439
},
34333440
500
34343441
);

tests/phpunit/tests/rest-api/rest-server.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,33 @@ public function test_error_to_response_with_additional_data() {
592592
$this->assertSame( array( array( 'status' => 400 ) ), $response->get_data()['additional_data'] );
593593
}
594594

595+
/**
596+
* @ticket 64901
597+
*/
598+
public function test_error_to_response_with_stdclass_data() {
599+
$error = new WP_Error( 'test', 'test', (object) array( 'status' => 400 ) );
600+
601+
$response = rest_convert_error_to_response( $error );
602+
$this->assertInstanceOf( WP_REST_Response::class, $response );
603+
604+
// stdClass data should not cause a fatal, status should default to 500.
605+
$this->assertSame( 500, $response->get_status() );
606+
}
607+
608+
/**
609+
* @ticket 64901
610+
*/
611+
public function test_error_to_response_with_multi_status_non_numeric_status() {
612+
$error = new WP_Error( 'test', 'test', array( 'status' => array( 'feeling' => 'happy' ) ) );
613+
$error->add_data( array( 'status' => 400 ), 'test' );
614+
$error->add_data( array( 'status' => array( 'feeling' => 'bleh' ) ), 'test' );
615+
616+
$response = rest_convert_error_to_response( $error );
617+
$this->assertInstanceOf( WP_REST_Response::class, $response );
618+
619+
$this->assertSame( 400, $response->get_status() );
620+
}
621+
595622
public function test_rest_error() {
596623
$data = array(
597624
'code' => 'wp-api-test-error',

0 commit comments

Comments
 (0)