Make WordPress Core

Changeset 46454


Ignore:
Timestamp:
10/09/2019 05:34:20 PM (5 years ago)
Author:
kadamwhite
Message:

REST API: Do not addslash when receiving meta arrays of non-string values.

Slashing non-string data caused PUT requests containing unmodified meta arrays of integers to fail the check against the existing stored meta value, causing a 500 when posting an unmodified response body back to the server.

Props TimothyBlynJacobs, augustuswm.
Fixes #48264.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/formatting.php

    r46451 r46454  
    54085408
    54095409/**
     5410 * Adds slashes to only string values in an array of values.
     5411 *
     5412 * This should be used when preparing data for core APIs that expect slashed data.
     5413 * This should not be used to escape data going directly into an SQL query.
     5414 *
     5415 * @since 5.3.0
     5416 *
     5417 * @param mixed $value Scalar or array of scalars.
     5418 * @return mixed Slashes $value
     5419 */
     5420function wp_slash_strings_only( $value ) {
     5421    return map_deep( $value, 'addslashes_strings_only' );
     5422}
     5423
     5424/**
     5425 * Adds slashes only if the provided value is a string.
     5426 *
     5427 * @since 5.3.0
     5428 *
     5429 * @param mixed $value
     5430 * @return mixed
     5431 */
     5432function addslashes_strings_only( $value ) {
     5433    return is_string( $value ) ? addslashes( $value ) : $value;
     5434}
     5435
     5436/**
    54105437 * Extract and return the first URL from passed content.
    54115438 *
  • trunk/src/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php

    r46346 r46454  
    366366        }
    367367
    368         if ( ! update_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) {
     368        if ( ! update_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash_strings_only( $value ) ) ) {
    369369            return new WP_Error(
    370370                'rest_meta_database_error',
  • trunk/tests/phpunit/tests/rest-api/rest-post-meta-fields.php

    r46186 r46454  
    22662266
    22672267    /**
     2268     * @ticket 48264
     2269     */
     2270    public function test_update_array_of_ints_meta() {
     2271        $this->grant_write_permission();
     2272        register_post_meta(
     2273            'post',
     2274            'items',
     2275            array(
     2276                'single'       => true,
     2277                'type'         => 'array',
     2278                'show_in_rest' => array(
     2279                    'schema' => array(
     2280                        'items' => array(
     2281                            'type' => 'integer',
     2282                        ),
     2283                    ),
     2284                ),
     2285            )
     2286        );
     2287
     2288        $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     2289        $request->set_body_params(
     2290            array(
     2291                'meta' => array(
     2292                    'items' => array( 1, 2, 3 ),
     2293                ),
     2294            )
     2295        );
     2296
     2297        rest_get_server()->dispatch( $request );
     2298        $response = rest_get_server()->dispatch( $request );
     2299        $this->assertEquals( 200, $response->get_status() );
     2300    }
     2301
     2302    /**
     2303     * @ticket 48264
     2304     */
     2305    public function test_update_array_of_ints_meta_stored_strings_are_updated() {
     2306        $this->grant_write_permission();
     2307        register_post_meta(
     2308            'post',
     2309            'items',
     2310            array(
     2311                'single'       => true,
     2312                'type'         => 'array',
     2313                'show_in_rest' => array(
     2314                    'schema' => array(
     2315                        'items' => array(
     2316                            'type' => 'integer',
     2317                        ),
     2318                    ),
     2319                ),
     2320            )
     2321        );
     2322
     2323        update_post_meta( self::$post_id, 'items', array( '1', '2', '3' ) );
     2324        $response = rest_get_server()->dispatch( new WP_REST_Request( 'GET', sprintf( '/wp/v2/posts/%d', self::$post_id ) ) );
     2325        $this->assertEquals( array( 1, 2, 3 ), $response->get_data()['meta']['items'] );
     2326
     2327        $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     2328        $request->set_body_params(
     2329            array(
     2330                'meta' => array(
     2331                    'items' => array( 1, 2, 3 ),
     2332                ),
     2333            )
     2334        );
     2335
     2336        $response = rest_get_server()->dispatch( $request );
     2337        $this->assertEquals( 200, $response->get_status() );
     2338        $this->assertSame( array( 1, 2, 3 ), get_post_meta( self::$post_id, 'items', true ) );
     2339    }
     2340
     2341    /**
     2342     * @ticket 48264
     2343     */
     2344    public function test_update_array_of_ints_meta_string_request_data_is_set_as_ints() {
     2345        $this->grant_write_permission();
     2346        register_post_meta(
     2347            'post',
     2348            'items',
     2349            array(
     2350                'single'       => true,
     2351                'type'         => 'array',
     2352                'show_in_rest' => array(
     2353                    'schema' => array(
     2354                        'items' => array(
     2355                            'type' => 'integer',
     2356                        ),
     2357                    ),
     2358                ),
     2359            )
     2360        );
     2361
     2362        update_post_meta( self::$post_id, 'items', array( 1, 2, 3 ) );
     2363
     2364        $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     2365        $request->set_body_params(
     2366            array(
     2367                'meta' => array(
     2368                    'items' => array( '1', '2', '3' ),
     2369                ),
     2370            )
     2371        );
     2372
     2373        $response = rest_get_server()->dispatch( $request );
     2374        $this->assertEquals( 200, $response->get_status() );
     2375        $this->assertSame( array( 1, 2, 3 ), get_post_meta( self::$post_id, 'items', true ) );
     2376    }
     2377
     2378    /**
     2379     * @ticket 48264
     2380     */
     2381    public function test_update_array_of_ints_meta_string_request_data_and_string_stored_data() {
     2382        $this->grant_write_permission();
     2383        register_post_meta(
     2384            'post',
     2385            'items',
     2386            array(
     2387                'single'       => true,
     2388                'type'         => 'array',
     2389                'show_in_rest' => array(
     2390                    'schema' => array(
     2391                        'items' => array(
     2392                            'type' => 'integer',
     2393                        ),
     2394                    ),
     2395                ),
     2396            )
     2397        );
     2398
     2399        update_post_meta( self::$post_id, 'items', array( '1', '2', '3' ) );
     2400
     2401        $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     2402        $request->set_body_params(
     2403            array(
     2404                'meta' => array(
     2405                    'items' => array( '1', '2', '3' ),
     2406                ),
     2407            )
     2408        );
     2409
     2410        $response = rest_get_server()->dispatch( $request );
     2411        $this->assertEquals( 200, $response->get_status() );
     2412        $this->assertSame( array( 1, 2, 3 ), get_post_meta( self::$post_id, 'items', true ) );
     2413    }
     2414
     2415    /**
     2416     * @ticket 48264
     2417     */
     2418    public function test_update_array_of_bools_meta() {
     2419        $this->grant_write_permission();
     2420        register_post_meta(
     2421            'post',
     2422            'items',
     2423            array(
     2424                'single'       => true,
     2425                'type'         => 'array',
     2426                'show_in_rest' => array(
     2427                    'schema' => array(
     2428                        'items' => array(
     2429                            'type' => 'boolean',
     2430                        ),
     2431                    ),
     2432                ),
     2433            )
     2434        );
     2435
     2436        $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     2437        $request->set_body_params(
     2438            array(
     2439                'meta' => array(
     2440                    'items' => array( true, false ),
     2441                ),
     2442            )
     2443        );
     2444
     2445        rest_get_server()->dispatch( $request );
     2446        $response = rest_get_server()->dispatch( $request );
     2447        $this->assertEquals( 200, $response->get_status() );
     2448    }
     2449
     2450    /**
     2451     * @ticket 48264
     2452     */
     2453    public function test_update_array_of_bools_meta_stored_strings_are_updated() {
     2454        $this->grant_write_permission();
     2455        register_post_meta(
     2456            'post',
     2457            'items',
     2458            array(
     2459                'single'       => true,
     2460                'type'         => 'array',
     2461                'show_in_rest' => array(
     2462                    'schema' => array(
     2463                        'items' => array(
     2464                            'type' => 'boolean',
     2465                        ),
     2466                    ),
     2467                ),
     2468            )
     2469        );
     2470
     2471        update_post_meta( self::$post_id, 'items', array( '1', '0' ) );
     2472
     2473        $response = rest_get_server()->dispatch( new WP_REST_Request( 'GET', sprintf( '/wp/v2/posts/%d', self::$post_id ) ) );
     2474        $this->assertEquals( array( true, false ), $response->get_data()['meta']['items'] );
     2475
     2476        $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     2477        $request->set_body_params(
     2478            array(
     2479                'meta' => array(
     2480                    'items' => array( true, false ),
     2481                ),
     2482            )
     2483        );
     2484
     2485        $response = rest_get_server()->dispatch( $request );
     2486        $this->assertEquals( 200, $response->get_status() );
     2487        $this->assertSame( array( true, false ), get_post_meta( self::$post_id, 'items', true ) );
     2488    }
     2489
     2490    /**
     2491     * @ticket 48264
     2492     */
     2493    public function test_update_array_of_bools_meta_string_request_data_is_set_as_bools() {
     2494        $this->grant_write_permission();
     2495        register_post_meta(
     2496            'post',
     2497            'items',
     2498            array(
     2499                'single'       => true,
     2500                'type'         => 'array',
     2501                'show_in_rest' => array(
     2502                    'schema' => array(
     2503                        'items' => array(
     2504                            'type' => 'boolean',
     2505                        ),
     2506                    ),
     2507                ),
     2508            )
     2509        );
     2510
     2511        update_post_meta( self::$post_id, 'items', array( true, false ) );
     2512
     2513        $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     2514        $request->set_body_params(
     2515            array(
     2516                'meta' => array(
     2517                    'items' => array( '1', '0' ),
     2518                ),
     2519            )
     2520        );
     2521
     2522        $response = rest_get_server()->dispatch( $request );
     2523        $this->assertEquals( 200, $response->get_status() );
     2524        $this->assertSame( array( true, false ), get_post_meta( self::$post_id, 'items', true ) );
     2525    }
     2526
     2527    /**
     2528     * @ticket 48264
     2529     */
     2530    public function test_update_array_of_bools_meta_string_request_data_and_string_stored_data() {
     2531        $this->grant_write_permission();
     2532        register_post_meta(
     2533            'post',
     2534            'items',
     2535            array(
     2536                'single'       => true,
     2537                'type'         => 'array',
     2538                'show_in_rest' => array(
     2539                    'schema' => array(
     2540                        'items' => array(
     2541                            'type' => 'boolean',
     2542                        ),
     2543                    ),
     2544                ),
     2545            )
     2546        );
     2547
     2548        update_post_meta( self::$post_id, 'items', array( '1', '0' ) );
     2549
     2550        $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     2551        $request->set_body_params(
     2552            array(
     2553                'meta' => array(
     2554                    'items' => array( '1', '0' ),
     2555                ),
     2556            )
     2557        );
     2558
     2559        $response = rest_get_server()->dispatch( $request );
     2560        $this->assertEquals( 200, $response->get_status() );
     2561        $this->assertSame( array( true, false ), get_post_meta( self::$post_id, 'items', true ) );
     2562    }
     2563
     2564    /**
     2565     * @ticket 48264
     2566     */
     2567    public function test_update_array_of_bools_with_string_values_stored_and_opposite_request_data() {
     2568        $this->grant_write_permission();
     2569        register_post_meta(
     2570            'post',
     2571            'items',
     2572            array(
     2573                'single'       => true,
     2574                'type'         => 'array',
     2575                'show_in_rest' => array(
     2576                    'schema' => array(
     2577                        'items' => array(
     2578                            'type' => 'boolean',
     2579                        ),
     2580                    ),
     2581                ),
     2582            )
     2583        );
     2584
     2585        update_post_meta( self::$post_id, 'items', array( '1', '0' ) );
     2586
     2587        $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     2588        $request->set_body_params(
     2589            array(
     2590                'meta' => array(
     2591                    'items' => array( false, true ),
     2592                ),
     2593            )
     2594        );
     2595
     2596        $response = rest_get_server()->dispatch( $request );
     2597        $this->assertEquals( 200, $response->get_status() );
     2598        $this->assertSame( array( false, true ), get_post_meta( self::$post_id, 'items', true ) );
     2599    }
     2600
     2601    /**
    22682602     * Internal function used to disable an insert query which
    22692603     * will trigger a wpdb error for testing purposes.
Note: See TracChangeset for help on using the changeset viewer.