REST API: Slash existing meta values when comparing with incoming meta upates.

When comparing the old and new values for a meta key being set, ensure both values are sanitized using the same logic so that equal values match.

props boonebgorges, dcavins, MattGeri, pilou69, TimothyBlynJacobs, kadamwhite.

Merges [43740] to trunk.

Fixes #42069.

git-svn-id: https://develop.svn.wordpress.org/trunk@44113 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Jonathan Desrosiers 2018-12-13 16:29:57 +00:00
parent 7a2fa10e28
commit c05b5d8b61
2 changed files with 95 additions and 5 deletions

View File

@ -317,19 +317,17 @@ abstract class WP_REST_Meta_Fields {
);
}
$meta_key = wp_slash( $meta_key );
$meta_value = wp_slash( $value );
// Do the exact same check for a duplicate value as in update_metadata() to avoid update_metadata() returning false.
$old_value = get_metadata( $meta_type, $object_id, $meta_key );
$subtype = get_object_subtype( $meta_type, $object_id );
if ( 1 === count( $old_value ) ) {
if ( $old_value[0] === $meta_value ) {
if ( (string) sanitize_meta( $meta_key, $value, $meta_type, $subtype ) === $old_value[0] ) {
return true;
}
}
if ( ! update_metadata( $meta_type, $object_id, $meta_key, $meta_value ) ) {
if ( ! update_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) {
return new WP_Error(
'rest_meta_database_error',
__( 'Could not update meta value in database.' ),

View File

@ -192,6 +192,48 @@ class WP_Test_REST_Post_Meta_Fields extends WP_Test_REST_TestCase {
)
);
register_meta(
'post',
'test_boolean_update',
array(
'single' => true,
'type' => 'boolean',
'sanitize_callback' => 'absint',
'show_in_rest' => true,
)
);
register_meta(
'post',
'test_textured_text_update',
array(
'single' => true,
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
'show_in_rest' => true,
)
);
register_meta(
'post',
'test_json_encoded',
array(
'single' => true,
'type' => 'string',
'show_in_rest' => true,
)
);
register_meta(
'post',
'test\'slashed\'key',
array(
'single' => true,
'type' => 'string',
'show_in_rest' => true,
)
);
/** @var WP_REST_Server $wp_rest_server */
global $wp_rest_server;
$wp_rest_server = new Spy_REST_Server;
@ -1255,6 +1297,56 @@ class WP_Test_REST_Post_Meta_Fields extends WP_Test_REST_TestCase {
return $data;
}
/**
* @ticket 42069
* @dataProvider data_update_value_return_success_with_same_value
*/
public function test_update_value_return_success_with_same_value( $meta_key, $meta_value ) {
add_post_meta( self::$post_id, $meta_key, $meta_value );
$this->grant_write_permission();
$data = array(
'meta' => array(
$meta_key => $meta_value,
),
);
$request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
$request->set_body_params( $data );
$response = rest_get_server()->dispatch( $request );
$this->assertEquals( 200, $response->get_status() );
}
public function data_update_value_return_success_with_same_value() {
return array(
array( 'test_boolean_update', false ),
array( 'test_boolean_update', true ),
array( 'test_textured_text_update', 'She said, "What about the > 10,000 penguins in the kitchen?"' ),
array( 'test_textured_text_update', "He's about to do something rash..." ),
array( 'test_json_encoded', json_encode( array( 'foo' => 'bar' ) ) ),
array( 'test\'slashed\'key', 'Hello' ),
);
}
/**
* @ticket 42069
*/
public function test_slashed_meta_key() {
add_post_meta( self::$post_id, 'test\'slashed\'key', 'Hello' );
$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
$response = rest_get_server()->dispatch( $request );
$data = $response->get_data();
$this->assertArrayHasKey( 'test\'slashed\'key', $data['meta'] );
$this->assertEquals( 'Hello', $data['meta']['test\'slashed\'key'] );
}
/**
* Internal function used to disable an insert query which
* will trigger a wpdb error for testing purposes.