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 preceding query have failed.

Props spacedmonkey, desrosj, pento.

Merges [43934] into trunk.

See #45299.

git-svn-id: https://develop.svn.wordpress.org/trunk@44272 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Jonathan Desrosiers 2018-12-17 18:38:13 +00:00
parent 6e546d482d
commit 5c6cc0f6ce
2 changed files with 101 additions and 7 deletions

View File

@ -2544,8 +2544,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;
}
@ -2585,11 +2587,13 @@ 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;

View File

@ -570,6 +570,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' ) );