REST API: Return error when JSON decoding fails.
If you send a request to the REST API with invalid JSON in body than it will now return a error. This assists developers if they accidentally send invalid JSON and wonder why their data appears to be ignored. Props rmccue. Fixes #38547. git-svn-id: https://develop.svn.wordpress.org/trunk@39109 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
973ade2a28
commit
f784a0481b
@ -651,11 +651,13 @@ class WP_REST_Request implements ArrayAccess {
|
|||||||
* Avoids parsing the JSON data until we need to access it.
|
* Avoids parsing the JSON data until we need to access it.
|
||||||
*
|
*
|
||||||
* @since 4.4.0
|
* @since 4.4.0
|
||||||
|
* @since 4.7.0 Returns error instance if value cannot be decoded.
|
||||||
* @access protected
|
* @access protected
|
||||||
|
* @return true|WP_Error True if the JSON data was passed or no JSON data was provided, WP_Error if invalid JSON was passed.
|
||||||
*/
|
*/
|
||||||
protected function parse_json_params() {
|
protected function parse_json_params() {
|
||||||
if ( $this->parsed_json ) {
|
if ( $this->parsed_json ) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->parsed_json = true;
|
$this->parsed_json = true;
|
||||||
@ -664,7 +666,7 @@ class WP_REST_Request implements ArrayAccess {
|
|||||||
$content_type = $this->get_content_type();
|
$content_type = $this->get_content_type();
|
||||||
|
|
||||||
if ( empty( $content_type ) || 'application/json' !== $content_type['value'] ) {
|
if ( empty( $content_type ) || 'application/json' !== $content_type['value'] ) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$params = json_decode( $this->get_body(), true );
|
$params = json_decode( $this->get_body(), true );
|
||||||
@ -676,10 +678,19 @@ class WP_REST_Request implements ArrayAccess {
|
|||||||
* might not be defined: https://core.trac.wordpress.org/ticket/27799
|
* might not be defined: https://core.trac.wordpress.org/ticket/27799
|
||||||
*/
|
*/
|
||||||
if ( null === $params && ( ! function_exists( 'json_last_error' ) || JSON_ERROR_NONE !== json_last_error() ) ) {
|
if ( null === $params && ( ! function_exists( 'json_last_error' ) || JSON_ERROR_NONE !== json_last_error() ) ) {
|
||||||
return;
|
// Ensure subsequent calls receive error instance.
|
||||||
|
$this->parsed_json = false;
|
||||||
|
|
||||||
|
$error_data = array(
|
||||||
|
'status' => WP_Http::BAD_REQUEST,
|
||||||
|
'json_error_code' => json_last_error(),
|
||||||
|
'json_error_message' => json_last_error_msg(),
|
||||||
|
);
|
||||||
|
return new WP_Error( 'rest_invalid_json', __( 'Invalid JSON body passed.' ), $error_data );
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->params['JSON'] = $params;
|
$this->params['JSON'] = $params;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -841,6 +852,12 @@ class WP_REST_Request implements ArrayAccess {
|
|||||||
* WP_Error if required parameters are missing.
|
* WP_Error if required parameters are missing.
|
||||||
*/
|
*/
|
||||||
public function has_valid_params() {
|
public function has_valid_params() {
|
||||||
|
// If JSON data was passed, check for errors.
|
||||||
|
$json_error = $this->parse_json_params();
|
||||||
|
if ( is_wp_error( $json_error ) ) {
|
||||||
|
return $json_error;
|
||||||
|
}
|
||||||
|
|
||||||
$attributes = $this->get_attributes();
|
$attributes = $this->get_attributes();
|
||||||
$required = array();
|
$required = array();
|
||||||
|
|
||||||
|
@ -399,6 +399,21 @@ class Tests_REST_Request extends WP_UnitTestCase {
|
|||||||
$this->assertEquals( 'rest_invalid_param', $valid->get_error_code() );
|
$this->assertEquals( 'rest_invalid_param', $valid->get_error_code() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_has_valid_params_json_error() {
|
||||||
|
if ( version_compare( PHP_VERSION, '5.3', '<' ) ) {
|
||||||
|
return $this->markTestSkipped( 'JSON validation is only available for PHP 5.3+' );
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->request->set_header( 'Content-Type', 'application/json' );
|
||||||
|
$this->request->set_body( '{"invalid": JSON}' );
|
||||||
|
|
||||||
|
$valid = $this->request->has_valid_params();
|
||||||
|
$this->assertWPError( $valid );
|
||||||
|
$this->assertEquals( 'rest_invalid_json', $valid->get_error_code() );
|
||||||
|
$data = $valid->get_error_data();
|
||||||
|
$this->assertEquals( JSON_ERROR_SYNTAX, $data['json_error_code'] );
|
||||||
|
}
|
||||||
|
|
||||||
public function test_has_multiple_invalid_params_validate_callback() {
|
public function test_has_multiple_invalid_params_validate_callback() {
|
||||||
$this->request->set_url_params( array(
|
$this->request->set_url_params( array(
|
||||||
'someinteger' => '123',
|
'someinteger' => '123',
|
||||||
|
Loading…
Reference in New Issue
Block a user