Make WordPress Core

Changeset 41481


Ignore:
Timestamp:
09/19/2017 03:03:42 PM (7 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.

Merges [41470] to 3.8 branch.

Location:
branches/3.8
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/3.8

  • branches/3.8/src/wp-includes/wp-db.php

    r33996 r41481  
    10411041        $args = func_get_args();
    10421042        array_shift( $args );
     1043
    10431044        // If args were passed as an array (as in vsprintf), move them up
    1044         if ( isset( $args[0] ) && is_array($args[0]) )
     1045        if ( is_array( $args[0] ) && count( $args ) == 1 ) {
    10451046            $args = $args[0];
     1047        }
     1048
     1049        foreach ( $args as $arg ) {
     1050            if ( ! is_scalar( $arg ) ) {
     1051                _doing_it_wrong( 'wpdb::prepare', sprintf( 'Unsupported value type (%s).', gettype( $arg ) ), '3.8.22' );
     1052            }
     1053        }
     1054
    10461055        $query = str_replace( "'%s'", '%s', $query ); // in case someone mistakenly already singlequoted it
    10471056        $query = str_replace( '"%s"', '%s', $query ); // doublequote unquoting
  • branches/3.8/tests/phpunit/tests/db.php

    r33996 r41481  
    153153    }
    154154
     155    function test_prepare_sprintf() {
     156        global $wpdb;
     157
     158        $prepared = $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", 1, "admin" );
     159        $this->assertEquals( "SELECT * FROM $wpdb->users WHERE id = 1 AND user_login = 'admin'", $prepared );
     160    }
     161
     162    /**
     163     * @expectedIncorrectUsage wpdb::prepare
     164     */
     165    function test_prepare_sprintf_invalid_args() {
     166        global $wpdb;
     167
     168        $prepared = @$wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", 1, array( "admin" ) );
     169        $this->assertEquals( "SELECT * FROM $wpdb->users WHERE id = 1 AND user_login = ''", $prepared );
     170
     171        $prepared = @$wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", array( 1 ), "admin" );
     172        $this->assertEquals( "SELECT * FROM $wpdb->users WHERE id = 0 AND user_login = 'admin'", $prepared );
     173    }
     174
     175        function test_prepare_vsprintf() {
     176                global $wpdb;
     177
     178        $prepared = $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", array( 1, "admin" ) );
     179        $this->assertEquals( "SELECT * FROM $wpdb->users WHERE id = 1 AND user_login = 'admin'", $prepared );
     180    }
     181
     182    /**
     183     * @expectedIncorrectUsage wpdb::prepare
     184     */
     185    function test_prepare_vsprintf_invalid_args() {
     186        global $wpdb;
     187
     188        $prepared = @$wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", array( 1, array( "admin" ) ) );
     189        $this->assertEquals( "SELECT * FROM $wpdb->users WHERE id = 1 AND user_login = ''", $prepared );
     190
     191        $prepared = @$wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", array( array( 1 ), "admin" ) );
     192        $this->assertEquals( "SELECT * FROM $wpdb->users WHERE id = 0 AND user_login = 'admin'", $prepared );
     193        }
     194
    155195    function test_db_version() {
    156196        global $wpdb;
Note: See TracChangeset for help on using the changeset viewer.