WPDB: Check that $wpdb->last_result is countable before counting with it.

`wpdb::get_col()` iterates over `$wpdb->last_result`, which can be a non-countable value, should the preceeding query have failed.

Props spacedmonkey, desrosj.
See #45299.



git-svn-id: https://develop.svn.wordpress.org/branches/5.0@43934 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Gary Pendergast 2018-11-22 03:58:19 +00:00
parent b5f10f4d78
commit 48500bf839
2 changed files with 103 additions and 8 deletions

View File

@ -2456,8 +2456,10 @@ class wpdb {
$new_array = array();
// Extract the column values
for ( $i = 0, $j = count( $this->last_result ); $i < $j; $i++ ) {
$new_array[$i] = $this->get_var( null, $x, $i );
if ( $this->last_result ) {
for ( $i = 0, $j = count( $this->last_result ); $i < $j; $i++ ) {
$new_array[ $i ] = $this->get_var( null, $x, $i );
}
}
return $new_array;
}
@ -2497,11 +2499,14 @@ class wpdb {
} elseif ( $output == OBJECT_K ) {
// Return an array of row objects with keys from column 1
// (Duplicates are discarded)
foreach ( $this->last_result as $row ) {
$var_by_ref = get_object_vars( $row );
$key = array_shift( $var_by_ref );
if ( ! isset( $new_array[ $key ] ) )
$new_array[ $key ] = $row;
if ( $this->last_result ) {
foreach ( $this->last_result as $row ) {
$var_by_ref = get_object_vars( $row );
$key = array_shift( $var_by_ref );
if ( ! isset( $new_array[ $key ] ) ) {
$new_array[ $key ] = $row;
}
}
}
return $new_array;
} elseif ( $output == ARRAY_A || $output == ARRAY_N ) {

View File

@ -156,7 +156,7 @@ class Tests_DB extends WP_UnitTestCase {
* @dataProvider data_like_query
* @param $data string The haystack, raw.
* @param $like string The like phrase, raw.
* @param $result string The expected comparison result; '1' = true, '0' = false
* @param $result string The expected comparison result; '1' = true, '0' = false
*/
function test_like_query( $data, $like, $result ) {
global $wpdb;
@ -559,6 +559,96 @@ class Tests_DB extends WP_UnitTestCase {
$this->assertEquals( 'Walter Sobchak', $row->display_name );
}
/**
* Test the `get_col()` method.
*
* @param string|null $query The query to run.
* @param string|array $expected The expected resulting value.
* @param arrray|string|null $last_result The value to assign to `$wpdb->last_result`.
* @param int|string $column The column index to retrieve.
*
* @dataProvider data_test_get_col
*
* @ticket 45299
*/
function test_get_col( $query, $expected, $last_result, $column ) {
global $wpdb;
$wpdb->last_result = $last_result;
$result = $wpdb->get_col( $query, $column );
if ( $query ) {
$this->assertSame( $query, $wpdb->last_query );
}
if ( is_array( $expected ) ) {
$this->assertSame( $expected, $result );
} else {
$this->assertContains( $expected, $result );
}
}
/**
* Data provider for testing `get_col()`.
*
* @return array {
* Arguments for testing `get_col()`.
*
* @type string|null $query The query to run.
* @type string|array $expected The resulting expected value.
* @type arrray|string|null $last_result The value to assign to `$wpdb->last_result`.
* @type int|string $column The column index to retrieve.
*/
function data_test_get_col() {
global $wpdb;
return array(
array(
"SELECT display_name FROM $wpdb->users",
'admin',
array(),
0,
),
array(
"SELECT user_login, user_email FROM $wpdb->users",
'admin',
array(),
0,
),
array(
"SELECT user_login, user_email FROM $wpdb->users",
'admin@example.org',
array(),
1,
),
array(
"SELECT user_login, user_email FROM $wpdb->users",
'admin@example.org',
array(),
'1',
),
array(
"SELECT user_login, user_email FROM $wpdb->users",
array( null ),
array(),
3,
),
array(
'',
array(),
null,
0,
),
array(
null,
array(),
'',
0
),
);
}
function test_replace() {
global $wpdb;
$rows1 = $wpdb->insert( $wpdb->users, array( 'display_name' => 'Walter Sobchak' ) );