Ticket #32165: 32165.5.diff
File 32165.5.diff, 5.4 KB (added by , 10 years ago) |
---|
-
src/wp-includes/wp-db.php
2710 2710 $queries = array(); 2711 2711 foreach ( $data as $col => $value ) { 2712 2712 if ( ! empty( $value['db'] ) ) { 2713 if ( ! isset( $queries[ $value['charset'] ] ) ) {2714 $queries[ $value['charset'] ] = array();2715 }2716 2717 2713 // We're going to need to truncate by characters or bytes, depending on the length value we have. 2718 2714 if ( 'byte' === $value['length']['type'] ) { 2719 // Split the CONVERT() calls by charset, so we can make sure the connection is right2720 $ queries[ $value['charset'] ][ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING binary ), %.0f ) USING {$value['charset']} )", $value['value'], $value['length']['length'] );2715 // Using binary causes LEFT() to truncate by bytes. 2716 $charset = 'binary'; 2721 2717 } else { 2722 $ queries[ $value['charset'] ][ $col ] = $this->prepare( "LEFT( CONVERT( %s USING {$value['charset']} ), %.0f )", $value['value'], $value['length']['length'] );2718 $charset = $value['charset']; 2723 2719 } 2724 2720 2721 $queries[ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING $charset ), %.0f ) USING {$this->charset} )", $value['value'], $value['length']['length'] ); 2722 2725 2723 unset( $data[ $col ]['db'] ); 2726 2724 } 2727 2725 } 2728 2726 2729 $ connection_charset = $this->charset;2730 foreach ( $queries as $c harset=> $query ) {2727 $sql = array(); 2728 foreach ( $queries as $column => $query ) { 2731 2729 if ( ! $query ) { 2732 2730 continue; 2733 2731 } 2734 2732 2735 // Change the charset to match the string(s) we're converting 2736 if ( $charset !== $connection_charset ) { 2737 $connection_charset = $charset; 2738 $this->set_charset( $this->dbh, $charset ); 2739 } 2733 $sql[] = $query . " AS x_$column"; 2734 } 2740 2735 2741 $this->check_current_query = false; 2742 2743 $sql = array(); 2744 foreach ( $query as $column => $column_query ) { 2745 $sql[] = $column_query . " AS x_$column"; 2746 } 2747 2748 $row = $this->get_row( "SELECT " . implode( ', ', $sql ), ARRAY_A ); 2749 if ( ! $row ) { 2750 $this->set_charset( $this->dbh, $connection_charset ); 2751 return new WP_Error( 'wpdb_strip_invalid_text_failure' ); 2752 } 2753 2754 foreach ( array_keys( $query ) as $column ) { 2755 $data[ $column ]['value'] = $row["x_$column"]; 2756 } 2736 $this->check_current_query = false; 2737 $row = $this->get_row( "SELECT " . implode( ', ', $sql ), ARRAY_A ); 2738 if ( ! $row ) { 2739 return new WP_Error( 'wpdb_strip_invalid_text_failure' ); 2757 2740 } 2758 2741 2759 // Don't forget to change the charset back! 2760 if ( $connection_charset !== $this->charset ) { 2761 $this->set_charset( $this->dbh ); 2742 foreach ( array_keys( $data ) as $column ) { 2743 $data[ $column ]['value'] = $row["x_$column"]; 2762 2744 } 2763 2745 } 2764 2746 -
tests/phpunit/tests/db/charset.php
244 244 'expected' => str_repeat( "\xcc\xe3", 5 ), 245 245 'length' => array( 'type' => 'byte', 'length' => 10 ), 246 246 ), 247 'ujis_with_utf8_connection' => array( 248 'charset' => 'ujis', 249 'connection_charset' => 'utf8', 250 'value' => '自動下書き', 251 'expected' => '自動下書き', 252 'length' => array( 'type' => 'byte', 'length' => 100 ), 253 ), 254 'ujis_with_utf8_connection_char_length' => array( 255 'charset' => 'ujis', 256 'connection_charset' => 'utf8', 257 'value' => '自動下書き', 258 'expected' => '自動下書', 259 'length' => array( 'type' => 'char', 'length' => 4 ), 260 ), 261 'ujis_with_utf8_connection_byte_length' => array( 262 'charset' => 'ujis', 263 'connection_charset' => 'utf8', 264 'value' => '自動下書き', 265 'expected' => '自動', 266 'length' => array( 'type' => 'byte', 'length' => 6 ), 267 ), 247 268 'false' => array( 248 269 // false is a column with no character set (ie, a number column) 249 270 'charset' => false, … … 289 310 foreach ( $fields as $test_case => $field ) { 290 311 $expected = $field; 291 312 $expected['value'] = $expected['expected']; 292 unset( $expected['expected'], $field['expected'] );313 unset( $expected['expected'], $field['expected'], $expected['connection_charset'] ); 293 314 294 315 // We're keeping track of these for our multiple-field test. 295 316 $multiple[] = $field; … … 303 324 $data_provider[] = array( $data, $expected, $test_case ); 304 325 } 305 326 306 // Time for our test of multiple fields at once.307 $data_provider[] = array( $multiple, $multiple_expected, 'multiple fields/charsets' );308 309 327 return $data_provider; 310 328 } 311 329 … … 318 336 $this->markTestSkipped( 'This test fails in PHP 5.2 on Windows. See https://core.trac.wordpress.org/ticket/31262' ); 319 337 } 320 338 339 $charset = self::$_wpdb->charset; 340 if ( isset( $data[0]['connection_charset'] ) ) { 341 $new_charset = $data[0]['connection_charset']; 342 unset( $data[0]['connection_charset'] ); 343 } else { 344 $new_charset = $data[0]['charset']; 345 } 346 347 self::$_wpdb->charset = $new_charset; 348 self::$_wpdb->set_charset( self::$_wpdb->dbh, $new_charset ); 349 321 350 $actual = self::$_wpdb->strip_invalid_text( $data ); 351 352 self::$_wpdb->charset = $charset; 353 self::$_wpdb->set_charset( self::$_wpdb->dbh, $charset ); 354 322 355 $this->assertSame( $expected, $actual, $message ); 323 356 } 324 357