WPDB: ::strip_text_from_query() doesn't pass a length to ::strip_invalid_text(), which was causing queries to fail when they contained characters that needed to be sanity checked by MySQL.

Props dd32, mdawaffe, pento.

Fixes #32279.



git-svn-id: https://develop.svn.wordpress.org/trunk@33310 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Gary Pendergast 2015-07-17 07:06:33 +00:00
parent bea2bf1502
commit 7217a4f6e5
2 changed files with 43 additions and 3 deletions

View File

@ -2629,8 +2629,13 @@ class wpdb {
if ( is_array( $value['length'] ) ) {
$length = $value['length']['length'];
$truncate_by_byte_length = 'byte' === $value['length']['type'];
} else {
$length = false;
// Since we have no length, we'll never truncate.
// Initialize the variable to false. true would take us
// through an unnecessary (for this case) codepath below.
$truncate_by_byte_length = false;
}
// There's no charset to work with.
@ -2643,8 +2648,6 @@ class wpdb {
continue;
}
$truncate_by_byte_length = 'byte' === $value['length']['type'];
$needs_validation = true;
if (
// latin1 can store any byte sequence
@ -2718,7 +2721,12 @@ class wpdb {
$charset = $value['charset'];
}
if ( is_array( $value['length'] ) ) {
$queries[ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING $charset ), %.0f ) USING {$this->charset} )", $value['value'], $value['length']['length'] );
} else if ( 'binary' !== $charset ) {
// If we don't have a length, there's no need to convert binary - it will always return the same result.
$queries[ $col ] = $this->prepare( "CONVERT( CONVERT( %s USING $charset ) USING {$this->charset} )", $value['value'] );
}
unset( $data[ $col ]['db'] );
}

View File

@ -214,6 +214,21 @@ class Tests_DB_Charset extends WP_UnitTestCase {
'expected' => "\xd8ord\xd0ress",
'length' => array( 'type' => 'char', 'length' => 100 ),
),
'cp1251_no_length' => array(
'charset' => 'cp1251',
'value' => "\xd8ord\xd0ress",
'expected' => "\xd8ord\xd0ress",
'length' => false,
),
'cp1251_no_length_ascii' => array(
'charset' => 'cp1251',
'value' => "WordPress",
'expected' => "WordPress",
'length' => false,
// Don't set 'ascii' => true/false.
// That's a different codepath than it being unset even if
// three's only only ASCII in the value.
),
'cp1251_char_length' => array(
'charset' => 'cp1251',
'value' => str_repeat( "\xd8\xd0", 10 ),
@ -807,4 +822,21 @@ class Tests_DB_Charset extends WP_UnitTestCase {
$stripped = $wpdb->strip_invalid_text_for_column( $wpdb->comments, 'comment_agent', str_repeat( 'A', 256 ) );
$this->assertEquals( 255, strlen( $stripped ) );
}
/**
* @ticket 32279
*/
function test_strip_invalid_text_from_query_cp1251_is_safe() {
$tablename = 'test_cp1251_query_' . rand_str( 5 );
if ( ! self::$_wpdb->query( "CREATE TABLE $tablename ( a VARCHAR(50) ) DEFAULT CHARSET 'cp1251'" ) ) {
$this->markTestSkipped( "Test requires the 'cp1251' charset" );
}
$safe_query = "INSERT INTO $tablename( `a` ) VALUES( 'safe data' )";
$stripped_query = self::$_wpdb->strip_invalid_text_from_query( $safe_query );
self::$_wpdb->query( "DROP TABLE $tablename" );
$this->assertEquals( $safe_query, $stripped_query );
}
}