From 30ce242435393cfe629feffcba6e1f086af7205c Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 13 Jan 2020 13:34:06 +0100 Subject: [PATCH] Fix #79106: PDO may fetch wrong column indexes with PDO::FETCH_BOTH Column names can be numeric strings, so we have to make sure to insert the column values with the appropriate numeric keys, instead of adding them. --- NEWS | 4 ++ ext/pdo/pdo_stmt.c | 5 +-- ext/pdo/tests/bug_79106.phpt | 44 +++++++++++++++++++ ext/pdo/tests/bug_79106_collision.phpt | 38 ++++++++++++++++ ext/pdo_mysql/tests/bug_61411.phpt | 2 +- ext/pdo_mysql/tests/pdo_mysql_fetch_both.phpt | 26 ----------- 6 files changed, 89 insertions(+), 30 deletions(-) create mode 100644 ext/pdo/tests/bug_79106.phpt create mode 100644 ext/pdo/tests/bug_79106_collision.phpt diff --git a/NEWS b/NEWS index 8f20e99211..bc01882695 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,10 @@ PHP NEWS . Fixed bug #79084 (mysqlnd may fetch wrong column indexes with MYSQLI_BOTH). (cmb) +- PDO: + . Fixed bug #79106 (PDO may fetch wrong column indexes with PDO::FETCH_BOTH). + (cmb) + 23 Jan 2020, PHP 7.3.14 - Core diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 873f977fb6..3aaf145c9f 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -1028,10 +1028,9 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, enum pdo_ case PDO_FETCH_USE_DEFAULT: case PDO_FETCH_BOTH: zend_symtable_update(Z_ARRVAL_P(return_value), stmt->columns[i].name, &val); - if (Z_REFCOUNTED(val)) { - Z_ADDREF(val); + if (zend_hash_index_add(Z_ARRVAL_P(return_value), i, &val) != NULL) { + Z_TRY_ADDREF(val); } - zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &val); break; case PDO_FETCH_NAMED: diff --git a/ext/pdo/tests/bug_79106.phpt b/ext/pdo/tests/bug_79106.phpt new file mode 100644 index 0000000000..06e36aec74 --- /dev/null +++ b/ext/pdo/tests/bug_79106.phpt @@ -0,0 +1,44 @@ +--TEST-- +Bug #79106 (PDO may fetch wrong column indexes with PDO::FETCH_BOTH) +--SKIPIF-- +getMessage()); +} +if ($db->query('SELECT 1 as "1"') === false) { + die('skip driver does not support quoted numeric identifiers'); +} +?> +--FILE-- +query('SELECT 0 as "2007", 0 as "2008", 0 as "2020"'); +var_dump($stmt->fetchAll()); +?> +--EXPECT-- +array(1) { + [0]=> + array(6) { + [2007]=> + string(1) "0" + [0]=> + string(1) "0" + [2008]=> + string(1) "0" + [1]=> + string(1) "0" + [2020]=> + string(1) "0" + [2]=> + string(1) "0" + } +} diff --git a/ext/pdo/tests/bug_79106_collision.phpt b/ext/pdo/tests/bug_79106_collision.phpt new file mode 100644 index 0000000000..8dcb9d997b --- /dev/null +++ b/ext/pdo/tests/bug_79106_collision.phpt @@ -0,0 +1,38 @@ +--TEST-- +Bug #79106 (PDO may fetch wrong column indexes with PDO::FETCH_BOTH) - collision +--SKIPIF-- +getMessage()); +} +if ($db->query('SELECT 1 as "1"') === false) { + die('skip driver does not support quoted numeric identifiers'); +} +?> +--FILE-- +query('SELECT 11111 as "1", 22222 as "2"'); +var_dump($stmt->fetchAll()); +?> +--EXPECT-- +array(1) { + [0]=> + array(3) { + [1]=> + string(5) "11111" + [0]=> + string(5) "11111" + [2]=> + string(5) "22222" + } +} diff --git a/ext/pdo_mysql/tests/bug_61411.phpt b/ext/pdo_mysql/tests/bug_61411.phpt index d840f222f1..f84945242c 100644 --- a/ext/pdo_mysql/tests/bug_61411.phpt +++ b/ext/pdo_mysql/tests/bug_61411.phpt @@ -47,7 +47,7 @@ print "done!"; array(2) { [1]=> int(1) - [2]=> + [0]=> int(1) } done! diff --git a/ext/pdo_mysql/tests/pdo_mysql_fetch_both.phpt b/ext/pdo_mysql/tests/pdo_mysql_fetch_both.phpt index 9303a3119d..8c0a14ffc0 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_fetch_both.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_fetch_both.phpt @@ -59,30 +59,4 @@ $db = MySQLPDOTest::factory(); print "done!"; ?> --EXPECT-- -[002] Suspicious FETCH_BOTH result, dumping -array(2) { - [0]=> - string(1) "1" - [1]=> - string(1) "1" -} -array(2) { - [1]=> - string(1) "1" - [2]=> - string(1) "1" -} -[002] Expected differes from returned data, dumping -array(2) { - [0]=> - string(1) "1" - [1]=> - string(1) "1" -} -array(2) { - [1]=> - string(1) "1" - [2]=> - string(1) "1" -} done! -- 2.50.1