REST API: Return `WP_Error` when a client is attempting to update an option with a non-scalar value to `null`.

A `null` value is returned in the response for any option that has a non-scalar value.

To protect clients from accidentally including the `null` values from a response object in a request, we do not allow options with non-scalar values to be updated to `null`. Without this added protection a client could mistakenly delete all options that have non-scalar values from the database.

Props joehoyle, rachelbaker.
Fixes #38527.
Built from https://develop.svn.wordpress.org/trunk@38982


git-svn-id: http://core.svn.wordpress.org/trunk@38925 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Rachel Baker 2016-10-27 16:08:45 +00:00
parent 432f5e76b2
commit 4a37a04d0f
2 changed files with 29 additions and 3 deletions

View File

@ -95,6 +95,12 @@ class WP_REST_Settings_Controller extends WP_REST_Controller {
* @return mixed
*/
protected function prepare_value( $value, $schema ) {
// If the value is not a scalar, it's not possible to cast it to
// anything.
if ( ! is_scalar( $value ) ) {
return null;
}
switch ( $schema['type'] ) {
case 'string':
return (string) $value;
@ -141,9 +147,29 @@ class WP_REST_Settings_Controller extends WP_REST_Controller {
continue;
}
// A null value means reset the option, which is essentially deleting it
// from the database and then relying on the default value.
/**
* A `null` value for an option would have the same effect as
* deleting the option from the database, and relying on the
* default value.
*/
if ( is_null( $request[ $name ] ) ) {
/**
* A `null` value is returned in the response for any option
* that has a non-scalar value.
*
* To protect clients from accidentally including the `null`
* values from a response object in a request, we do not allow
* options with non-scalar values to be updated to `null`.
* Without this added protection a client could mistakenly
* delete all options that have non-scalar values from the
* database.
*/
if ( ! is_scalar( get_option( $args['option_name'], false ) ) ) {
return new WP_Error(
'rest_invalid_stored_value', sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ), array( 'status' => 500 )
);
}
delete_option( $args['option_name'] );
} else {
update_option( $args['option_name'], $request[ $name ] );

View File

@ -4,7 +4,7 @@
*
* @global string $wp_version
*/
$wp_version = '4.7-alpha-38981';
$wp_version = '4.7-alpha-38982';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.