summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-12-11 16:35:03 +0100
committerNikita Popov <nikita.ppv@gmail.com>2020-12-11 16:35:03 +0100
commitccb7f1c7d8518dc4548273a5acd578c57d47cc0c (patch)
treea1397038e119cefbd4ee7d3358f4e0b76b892edb
parent7a89157f8c440bccdd0317c1f460d2a916c5896c (diff)
downloadphp-git-ccb7f1c7d8518dc4548273a5acd578c57d47cc0c.tar.gz
Fixed bug #79132
Following cmb's suggestion and replacing the counter with a check against the bound_params HT, which ensures that both cannot go out of sync.
-rw-r--r--NEWS2
-rw-r--r--ext/pdo_mysql/mysql_driver.c1
-rw-r--r--ext/pdo_mysql/mysql_statement.c3
-rw-r--r--ext/pdo_mysql/php_pdo_mysql_int.h1
-rw-r--r--ext/pdo_mysql/tests/bug79132.phpt66
5 files changed, 69 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index b43b0a09a6..38e86d2619 100644
--- a/NEWS
+++ b/NEWS
@@ -59,6 +59,8 @@ PHP NEWS
. Fixed bug #62889 (LOAD DATA INFILE broken). (Nikita)
. Fixed bug #67004 (Executing PDOStatement::fetch() more than once prevents
releasing resultset). (Nikita)
+ . Fixed bug #79132 (PDO re-uses parameter values from earlier calls to
+ execute()). (Nikita)
- Phar:
. Fixed bug #73809 (Phar Zip parse crash - mmap fail). (cmb)
diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c
index 0a0526d954..980a285c0d 100644
--- a/ext/pdo_mysql/mysql_driver.c
+++ b/ext/pdo_mysql/mysql_driver.c
@@ -229,7 +229,6 @@ static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len
S->num_params = mysql_stmt_param_count(S->stmt);
if (S->num_params) {
- S->params_given = 0;
#ifdef PDO_USE_MYSQLND
S->params = NULL;
#else
diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c
index 7d75be2adc..871b7f9c7c 100644
--- a/ext/pdo_mysql/mysql_statement.c
+++ b/ext/pdo_mysql/mysql_statement.c
@@ -387,7 +387,6 @@ static int pdo_mysql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_da
strcpy(stmt->error_code, "HY093");
PDO_DBG_RETURN(0);
}
- S->params_given++;
#ifndef PDO_USE_MYSQLND
b = &S->params[param->paramno];
@@ -399,7 +398,7 @@ static int pdo_mysql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_da
PDO_DBG_RETURN(1);
case PDO_PARAM_EVT_EXEC_PRE:
- if (S->params_given < (unsigned int) S->num_params) {
+ if (zend_hash_num_elements(stmt->bound_params) < (unsigned int) S->num_params) {
/* too few parameter bound */
PDO_DBG_ERR("too few parameters bound");
strcpy(stmt->error_code, "HY093");
diff --git a/ext/pdo_mysql/php_pdo_mysql_int.h b/ext/pdo_mysql/php_pdo_mysql_int.h
index fe7f149d84..553437829e 100644
--- a/ext/pdo_mysql/php_pdo_mysql_int.h
+++ b/ext/pdo_mysql/php_pdo_mysql_int.h
@@ -141,7 +141,6 @@ typedef struct {
PDO_MYSQL_PARAM_BIND *bound_result;
my_bool *out_null;
zend_ulong *out_length;
- unsigned int params_given;
unsigned max_length:1;
/* Whether all result sets have been fully consumed.
* If this flag is not set, they need to be consumed during destruction. */
diff --git a/ext/pdo_mysql/tests/bug79132.phpt b/ext/pdo_mysql/tests/bug79132.phpt
new file mode 100644
index 0000000000..6535dbdee9
--- /dev/null
+++ b/ext/pdo_mysql/tests/bug79132.phpt
@@ -0,0 +1,66 @@
+--TEST--
+Bug #79132: PDO re-uses parameter values from earlier calls to execute()
+--SKIPIF--
+<?php
+require_once(__DIR__ . DIRECTORY_SEPARATOR . 'skipif.inc');
+require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
+MySQLPDOTest::skip();
+?>
+--FILE--
+<?php
+require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
+
+$pdo = MySQLPDOTest::factory();
+$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
+test($pdo);
+echo "\n";
+$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
+test($pdo);
+
+function test($pdo) {
+ $stmt = $pdo->prepare('select ? a, ? b');
+
+ $set = [
+ ['a', 'b'],
+ ['x'], /* second parameter is missing */
+ [1 => 'y'], /* first parameter is missing */
+ ];
+
+ foreach ($set as $params) {
+ try {
+ var_dump($stmt->execute($params), $stmt->fetchAll(PDO::FETCH_ASSOC));
+ } catch (PDOException $error) {
+ echo $error->getMessage() . "\n";
+ }
+ }
+}
+
+?>
+--EXPECT--
+bool(true)
+array(1) {
+ [0]=>
+ array(2) {
+ ["a"]=>
+ string(1) "a"
+ ["b"]=>
+ string(1) "b"
+ }
+}
+SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
+SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
+
+bool(true)
+array(1) {
+ [0]=>
+ array(2) {
+ ["a"]=>
+ string(1) "a"
+ ["b"]=>
+ string(1) "b"
+ }
+}
+SQLSTATE[HY093]: Invalid parameter number
+SQLSTATE[HY093]: Invalid parameter number