WordPress.org

Make WordPress Core

Ticket #32279: 32279.diff

File 32279.diff, 3.7 KB (added by dd32, 5 years ago)
  • src/wp-includes/wp-db.php

    class wpdb { 
    26932693                        }
    26942694
    26952695                        // We couldn't use any local conversions, send it to the DB.
    26962696                        $value['db'] = $db_check_string = true;
    26972697                }
    26982698                unset( $value ); // Remove by reference.
    26992699
    27002700                if ( $db_check_string ) {
    27012701                        $queries = array();
    27022702                        foreach ( $data as $col => $value ) {
    27032703                                if ( ! empty( $value['db'] ) ) {
    27042704                                        if ( ! isset( $queries[ $value['charset'] ] ) ) {
    27052705                                                $queries[ $value['charset'] ] = array();
    27062706                                        }
    27072707
    2708                                         // We're going to need to truncate by characters or bytes, depending on the length value we have.
    2709                                         if ( 'byte' === $value['length']['type'] ) {
    2710                                                 // Split the CONVERT() calls by charset, so we can make sure the connection is right
    2711                                                 $queries[ $value['charset'] ][ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING binary ), %d ) USING {$value['charset']} )", $value['value'], $value['length']['length'] );
     2708                                        if ( is_array( $value['length'] ) ) {
     2709                                                // We're going to need to truncate by characters or bytes, depending on the length value we have.
     2710                                                if ( 'byte' === $value['length']['type'] ) {
     2711                                                        // Split the CONVERT() calls by charset, so we can make sure the connection is right
     2712                                                        $queries[ $value['charset'] ][ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING binary ), %d ) USING {$value['charset']} )", $value['value'], $value['length']['length'] );
     2713                                                } else {
     2714                                                        $queries[ $value['charset'] ][ $col ] = $this->prepare( "LEFT( CONVERT( %s USING {$value['charset']} ), %d )", $value['value'], $value['length']['length'] );
     2715                                                }
    27122716                                        } else {
    2713                                                 $queries[ $value['charset'] ][ $col ] = $this->prepare( "LEFT( CONVERT( %s USING {$value['charset']} ), %d )", $value['value'], $value['length']['length'] );
     2717                                                $queries[ $value['charset'] ][ $col ] = $this->prepare( "CONVERT( %s USING {$value['charset']} )", $value['value'] );
    27142718                                        }
    27152719
    27162720                                        unset( $data[ $col ]['db'] );
    27172721                                }
    27182722                        }
    27192723
    27202724                        $connection_charset = $this->charset;
    27212725                        foreach ( $queries as $charset => $query ) {
    27222726                                if ( ! $query ) {
    27232727                                        continue;
    27242728                                }
    27252729
    27262730                                // Change the charset to match the string(s) we're converting
    27272731                                if ( $charset !== $connection_charset ) {
    27282732                                        $connection_charset = $charset;
  • tests/phpunit/tests/db/charset.php

    class Tests_DB_Charset extends WP_UnitTe 
    762762
    763763                self::$_wpdb->query( $drop );
    764764        }
    765765
    766766        function test_strip_invalid_text_for_column_bails_if_ascii_input_too_long() {
    767767                global $wpdb;
    768768
    769769                // TEXT column
    770770                $stripped = $wpdb->strip_invalid_text_for_column( $wpdb->comments, 'comment_content', str_repeat( 'A', 65536 ) );
    771771                $this->assertEquals( 65535, strlen( $stripped ) );
    772772
    773773                // VARCHAR column
    774774                $stripped = $wpdb->strip_invalid_text_for_column( $wpdb->comments, 'comment_agent', str_repeat( 'A', 256 ) );
    775775                $this->assertEquals( 255, strlen( $stripped ) );
    776776        }
     777
     778        /**
     779         * @ticket 32279
     780         */
     781        function test_strip_invalid_text_from_query_cp1251_is_safe() {
     782                $tablename = 'test_cp1251_query_' . rand_str( 5 );
     783                if ( ! self::$_wpdb->query( "CREATE TABLE $tablename ( a VARCHAR(50) ) DEFAULT CHARSET 'cp1251'" ) ) {
     784                        $this->markTestSkipped( "Test requires the 'cp1251' charset" );
     785                }
     786
     787                $safe_query = "INSERT INTO $tablename( `a` ) VALUES( 'safe data' )";
     788                $stripped_query = self::$_wpdb->strip_invalid_text_from_query( $safe_query );
     789
     790                self::$_wpdb->query( "DROP TABLE $tablename" );
     791
     792                $this->assertEquals( $safe_query, $stripped_query );
     793        }
     794
    777795}