Make WordPress Core

Changeset 39437 for branches/4.7


Ignore:
Timestamp:
12/02/2016 10:04:06 PM (9 years ago)
Author:
rachelbaker
Message:

REST API: Return a WP_Error if meta property is not an array.

Fixes bug where a PHP Warning is currently thrown if a client sends a request where meta is not an array value.

Merges [39436] onto 4.7 branch.

Props timmydcrawford, jnylen0, rachelbaker, pento.
Fixes #38989 for 4.7.

Location:
branches/4.7
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/4.7

  • branches/4.7/src/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php

    r39328 r39437  
    118118     * @access public
    119119     *
    120      * @param WP_REST_Request $request   Full details about the request.
     120     * @param array           $meta      Array of meta parsed from the request.
    121121     * @param int             $object_id Object ID to fetch meta for.
    122122     * @return WP_Error|null WP_Error if one occurs, null on success.
    123123     */
    124     public function update_value( $request, $object_id ) {
     124    public function update_value( $meta, $object_id ) {
    125125        $fields = $this->get_registered_fields();
    126126        foreach ( $fields as $meta_key => $args ) {
    127127            $name = $args['name'];
    128             if ( ! array_key_exists( $name, $request ) ) {
     128            if ( ! array_key_exists( $name, $meta ) ) {
    129129                continue;
    130130            }
     
    134134             * from the database and then relying on the default value.
    135135             */
    136             if ( is_null( $request[ $name ] ) ) {
     136            if ( is_null( $meta[ $name ] ) ) {
    137137                $result = $this->delete_meta_value( $object_id, $meta_key, $name );
    138138                if ( is_wp_error( $result ) ) {
     
    142142            }
    143143
    144             $is_valid = rest_validate_value_from_schema( $request[ $name ], $args['schema'], 'meta.' . $name );
     144            $is_valid = rest_validate_value_from_schema( $meta[ $name ], $args['schema'], 'meta.' . $name );
    145145            if ( is_wp_error( $is_valid ) ) {
    146146                $is_valid->add_data( array( 'status' => 400 ) );
     
    148148            }
    149149
    150             $value = rest_sanitize_value_from_schema( $request[ $name ], $args['schema'] );
     150            $value = rest_sanitize_value_from_schema( $meta[ $name ], $args['schema'] );
    151151
    152152            if ( $args['single'] ) {
     
    392392            'context'     => array( 'view', 'edit' ),
    393393            'properties'  => array(),
     394            'arg_options' => array(
     395                'sanitize_callback' => null,
     396                'validate_callback' => array( $this, 'check_meta_is_array' ),
     397            ),
    394398        );
    395399
     
    445449        return $value;
    446450    }
     451
     452    /**
     453     * Check the 'meta' value of a request is an associative array.
     454     *
     455     * @since 4.7.0
     456     * @access public
     457     *
     458     * @param  mixed           $value   The meta value submitted in the request.
     459     * @param  WP_REST_Request $request Full details about the request.
     460     * @param  string          $param   The parameter name.
     461     * @return WP_Error|string The meta array, if valid, otherwise an error.
     462     */
     463    public function check_meta_is_array( $value, $request, $param ) {
     464        if ( ! is_array( $value ) ) {
     465            return false;
     466        }
     467
     468        return $value;
     469    }
    447470}
  • branches/4.7/tests/phpunit/tests/rest-api/rest-post-meta-fields.php

    r39328 r39437  
    787787    }
    788788
     789    /**
     790     * @ticket 38989
     791     */
     792    public function test_set_value_invalid_meta_string_request_type() {
     793        update_post_meta( self::$post_id, 'test_single', 'So I tied an onion to my belt, which was the style at the time.' );
     794        $post_original = get_post( self::$post_id );
     795
     796        $this->grant_write_permission();
     797
     798        $data = array(
     799            'title' => 'Ignore this title',
     800            'meta'  => 'Not an array.',
     801        );
     802
     803        $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     804        $request->set_body_params( $data );
     805
     806        $response = $this->server->dispatch( $request );
     807
     808        $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     809
     810        // The meta value should not have changed.
     811        $current_value = get_post_meta( self::$post_id, 'test_single', true );
     812        $this->assertEquals( 'So I tied an onion to my belt, which was the style at the time.', $current_value );
     813
     814        // Ensure the post title update was not processed.
     815        $post_updated = get_post( self::$post_id );
     816        $this->assertEquals( $post_original->post_title, $post_updated->post_title );
     817    }
     818
     819    /**
     820     * @ticket 38989
     821     */
     822    public function test_set_value_invalid_meta_float_request_type() {
     823        update_post_meta( self::$post_id, 'test_single', 'Now, to take the ferry cost a nickel, and in those days, nickels had pictures of bumblebees on them.' );
     824        $post_original = get_post( self::$post_id );
     825
     826        $this->grant_write_permission();
     827
     828        $data = array(
     829            'content' => 'Ignore this content.',
     830            'meta'    => 1.234,
     831        );
     832
     833        $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     834        $request->set_body_params( $data );
     835
     836        $response = $this->server->dispatch( $request );
     837        $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     838
     839        // The meta value should not have changed.
     840        $current_value = get_post_meta( self::$post_id, 'test_single', true );
     841        $this->assertEquals( 'Now, to take the ferry cost a nickel, and in those days, nickels had pictures of bumblebees on them.', $current_value );
     842
     843        // Ensure the post content update was not processed.
     844        $post_updated = get_post( self::$post_id );
     845        $this->assertEquals( $post_original->post_content, $post_updated->post_content );
     846    }
     847
    789848    public function test_remove_multi_value_db_error() {
    790849        add_post_meta( self::$post_id, 'test_multi', 'val1' );
Note: See TracChangeset for help on using the changeset viewer.