diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php index 921360e3ee..6d8239793e 100644 --- a/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php +++ b/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php @@ -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 ] ); diff --git a/wp-includes/version.php b/wp-includes/version.php index 1255581d3f..2c5642fc26 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -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.