Make WordPress Core

Changeset 41470


Ignore:
Timestamp:
09/19/2017 02:47:46 PM (9 years ago)
Author:
aaroncampbell
Message:

Database: Hardening for wpdb::prepare()

Previously if you passed an array of values for placeholders, additional values could be passed as well. Now additional values will be ignored.

Location:
trunk
Files:
2 edited

Legend:

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

    r41241 r41470  
    12371237                $args = func_get_args();
    12381238                array_shift( $args );
     1239
    12391240                // If args were passed as an array (as in vsprintf), move them up
    1240                 if ( isset( $args[0] ) && is_array($args[0]) )
     1241                if ( is_array( $args[0] ) && count( $args ) == 1 ) {
    12411242                        $args = $args[0];
     1243                }
     1244
     1245                foreach ( $args as $arg ) {
     1246                        if ( ! is_scalar( $arg ) ) {
     1247                                _doing_it_wrong( 'wpdb::prepare', sprintf( __( 'Unsupported value type (%s).' ), gettype( $arg ) ), '4.8.2' );
     1248                        }
     1249                }
     1250
    12421251                $query = str_replace( "'%s'", '%s', $query ); // in case someone mistakenly already singlequoted it
    12431252                $query = str_replace( '"%s"', '%s', $query ); // doublequote unquoting
  • trunk/tests/phpunit/tests/db.php

    r40544 r41470  
    355355        }
    356356
     357        function test_prepare_sprintf() {
     358                global $wpdb;
     359
     360                $prepared = $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", 1, "admin" );
     361                $this->assertEquals( "SELECT * FROM $wpdb->users WHERE id = 1 AND user_login = 'admin'", $prepared );
     362        }
     363
     364        /**
     365         * @expectedIncorrectUsage wpdb::prepare
     366         */
     367        function test_prepare_sprintf_invalid_args() {
     368                global $wpdb;
     369
     370                $prepared = @$wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", 1, array( "admin" ) );
     371                $this->assertEquals( "SELECT * FROM $wpdb->users WHERE id = 1 AND user_login = ''", $prepared );
     372
     373                $prepared = @$wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", array( 1 ), "admin" );
     374                $this->assertEquals( "SELECT * FROM $wpdb->users WHERE id = 0 AND user_login = 'admin'", $prepared );
     375        }
     376
     377        function test_prepare_vsprintf() {
     378                global $wpdb;
     379
     380                $prepared = $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", array( 1, "admin" ) );
     381                $this->assertEquals( "SELECT * FROM $wpdb->users WHERE id = 1 AND user_login = 'admin'", $prepared );
     382        }
     383
     384        /**
     385         * @expectedIncorrectUsage wpdb::prepare
     386         */
     387        function test_prepare_vsprintf_invalid_args() {
     388                global $wpdb;
     389
     390                $prepared = @$wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", array( 1, array( "admin" ) ) );
     391                $this->assertEquals( "SELECT * FROM $wpdb->users WHERE id = 1 AND user_login = ''", $prepared );
     392
     393                $prepared = @$wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", array( array( 1 ), "admin" ) );
     394                $this->assertEquals( "SELECT * FROM $wpdb->users WHERE id = 0 AND user_login = 'admin'", $prepared );
     395        }
     396
    357397        function test_db_version() {
    358398                global $wpdb;
Note: See TracChangeset for help on using the changeset viewer.