WordPress.org

Make WordPress Core

Changeset 41662


Ignore:
Timestamp:
10/02/2017 02:10:14 AM (4 years ago)
Author:
pento
Message:

Database: Throw a notice if wpdb::prepare() is called with an incorrect number of arguments

wpdb::prepare() currently gives no information if the number of arguments passed doesn't match the number of placeholders in the query. This change gives an explicit notice that the call was incorrect.

Also fixes an enrelated term meta test that was triggering this new notice.

Props thekt12 for the initial patch.
Fixes #42040.

Location:
trunk
Files:
3 edited

Legend:

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

    r41660 r41662  
    12521252        $query = preg_replace( '|(?<!%)%f|' , '%F', $query ); // Force floats to be locale unaware
    12531253        $query = preg_replace( '|(?<!%)%s|', "'%s'", $query ); // quote the strings, avoiding escaped strings like %%s
    1254         $query = preg_replace( '/%(?:%|$|([^dsF]))/', '%%\\1', $query ); // escape any unescaped percents
     1254        $query = preg_replace( '/%(?:%|$|([^dsF]))/', '%%\\1', $query ); // escape any unescaped percents
     1255
     1256        // Count the number of valid placeholders in the query
     1257        $placeholders = preg_match_all( '/(^|[^%]|(%%)+)%[sdF]/', $query );
     1258
     1259        if ( count ( $args ) !== $placeholders ) {
     1260            _doing_it_wrong( 'wpdb::prepare',
     1261                sprintf( __( 'The query does not contain the correct number of placeholders (%d) for the number of arguments passed (%d).' ),
     1262                    $placeholders,
     1263                    count( $args ) ),
     1264                '4.9.0'
     1265            );
     1266        }
     1267
    12551268        array_walk( $args, array( $this, 'escape_by_ref' ) );
    12561269        return @vsprintf( $query, $args );
     
    20472060
    20482061        $sql = "UPDATE `$table` SET $fields WHERE $conditions";
    2049 
     2062       
    20502063        $this->check_current_query = false;
    20512064        return $this->query( $this->prepare( $sql, $values ) );
  • trunk/tests/phpunit/tests/db.php

    r41629 r41662  
    376376    }
    377377
    378         function test_prepare_vsprintf() {
    379                 global $wpdb;
     378    function test_prepare_vsprintf() {
     379        global $wpdb;
    380380
    381381        $prepared = $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", array( 1, "admin" ) );
     
    394394        $prepared = @$wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", array( array( 1 ), "admin" ) );
    395395        $this->assertEquals( "SELECT * FROM $wpdb->users WHERE id = 0 AND user_login = 'admin'", $prepared );
    396         }
     396    }
     397
     398    /**
     399     * @ticket 42040
     400     * @dataProvider data_prepare_incorrect_arg_count
     401     * @expectedIncorrectUsage wpdb::prepare
     402     */
     403    public function test_prepare_incorrect_arg_count( $query, $args, $expected ) {
     404        global $wpdb;
     405
     406        // $query is the first argument to be passed to wpdb::prepare()
     407        array_unshift( $args, $query );
     408
     409        $prepared = @call_user_func_array( array( $wpdb, 'prepare' ), $args );
     410        $this->assertEquals( $expected, $prepared );
     411    }
     412
     413    public function data_prepare_incorrect_arg_count() {
     414        global $wpdb;
     415
     416        return array(
     417            array(
     418                "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s",     // Query
     419                array( 1, "admin", "extra-arg" ),                                   // ::prepare() args, to be passed via call_user_func_array
     420                "SELECT * FROM $wpdb->users WHERE id = 1 AND user_login = 'admin'", // Expected output
     421            ),
     422            array(
     423                "SELECT * FROM $wpdb->users WHERE id = %%%d AND user_login = %s",
     424                array( 1 ),
     425                false,
     426            ),
     427            array(
     428                "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s",
     429                array( array( 1, "admin", "extra-arg" ) ),
     430                "SELECT * FROM $wpdb->users WHERE id = 1 AND user_login = 'admin'",
     431            ),
     432            array(
     433                "SELECT * FROM $wpdb->users WHERE id = %d AND %% AND user_login = %s",
     434                array( 1, "admin", "extra-arg" ),
     435                "SELECT * FROM $wpdb->users WHERE id = 1 AND % AND user_login = 'admin'",
     436            ),
     437            array(
     438                "SELECT * FROM $wpdb->users WHERE id = %%%d AND %F AND %f AND user_login = %s",
     439                array( 1, 2.3, "4.5", "admin", "extra-arg" ),
     440                "SELECT * FROM $wpdb->users WHERE id = %1 AND 2.300000 AND 4.500000 AND user_login = 'admin'",
     441            ),
     442            array(
     443                "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s",
     444                array( array( 1 ), "admin", "extra-arg" ),
     445                "SELECT * FROM $wpdb->users WHERE id = 0 AND user_login = 'admin'",
     446            ),
     447            array(
     448                "SELECT * FROM $wpdb->users WHERE id = %d and user_nicename = %s and user_status = %d and user_login = %s",
     449                array( 1, "admin", 0 ),
     450                '',
     451            ),
     452            array(
     453                "SELECT * FROM $wpdb->users WHERE id = %d and user_nicename = %s and user_status = %d and user_login = %s",
     454                array( array( 1, "admin", 0 ) ),
     455                '',
     456            ),
     457            array(
     458                "SELECT * FROM $wpdb->users WHERE id = %d and %% and user_login = %s and user_status = %d and user_login = %s",
     459                array( 1, "admin", "extra-arg" ),
     460                '',
     461            ),
     462        );
     463    }
    397464
    398465    function test_db_version() {
  • trunk/tests/phpunit/tests/term/meta.php

    r40916 r41662  
    359359        register_taxonomy( 'wptests_tax', 'post' );
    360360        $t1 = wp_insert_term( 'Foo', 'wptests_tax' );
    361         add_term_meta( $t1, 'foo', 'bar' );
     361        add_term_meta( $t1['term_id'], 'foo', 'bar' );
    362362
    363363        register_taxonomy( 'wptests_tax_2', 'post' );
Note: See TracChangeset for help on using the changeset viewer.