summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--ext/pdo/pdo_stmt.c5
-rw-r--r--ext/pdo/tests/bug_79106.phpt44
-rw-r--r--ext/pdo/tests/bug_79106_collision.phpt38
-rw-r--r--ext/pdo_mysql/tests/bug_61411.phpt2
-rw-r--r--ext/pdo_mysql/tests/pdo_mysql_fetch_both.phpt26
6 files changed, 89 insertions, 30 deletions
diff --git a/NEWS b/NEWS
index ba070d30ae..0ae335681e 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.4.2
- Core:
diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index 67fce95137..684923e152 100644
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -1032,10 +1032,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--
+<?php
+if (!extension_loaded('pdo')) die('skip pdo extension not available');
+$dir = getenv('REDIR_TEST_DIR');
+if (!$dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+try {
+ $db = PDOTest::factory();
+} catch (PDOException $e) {
+ die('skip ' . $e->getMessage());
+}
+if ($db->query('SELECT 1 as "1"') === false) {
+ die('skip driver does not support quoted numeric identifiers');
+}
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR=' . dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$stmt = $db->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--
+<?php
+if (!extension_loaded('pdo')) die('skip pdo extension not available');
+$dir = getenv('REDIR_TEST_DIR');
+if (!$dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+try {
+ $db = PDOTest::factory();
+} catch (PDOException $e) {
+ die('skip ' . $e->getMessage());
+}
+if ($db->query('SELECT 1 as "1"') === false) {
+ die('skip driver does not support quoted numeric identifiers');
+}
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR=' . dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$stmt = $db->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 c5df174997..f12804ab5f 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 0e53d40deb..b28ba2a03c 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!