mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
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.
This commit is contained in:
parent
7a89157f8c
commit
ccb7f1c7d8
5 changed files with 69 additions and 4 deletions
2
NEWS
2
NEWS
|
@ -59,6 +59,8 @@ PHP NEWS
|
||||||
. Fixed bug #62889 (LOAD DATA INFILE broken). (Nikita)
|
. Fixed bug #62889 (LOAD DATA INFILE broken). (Nikita)
|
||||||
. Fixed bug #67004 (Executing PDOStatement::fetch() more than once prevents
|
. Fixed bug #67004 (Executing PDOStatement::fetch() more than once prevents
|
||||||
releasing resultset). (Nikita)
|
releasing resultset). (Nikita)
|
||||||
|
. Fixed bug #79132 (PDO re-uses parameter values from earlier calls to
|
||||||
|
execute()). (Nikita)
|
||||||
|
|
||||||
- Phar:
|
- Phar:
|
||||||
. Fixed bug #73809 (Phar Zip parse crash - mmap fail). (cmb)
|
. Fixed bug #73809 (Phar Zip parse crash - mmap fail). (cmb)
|
||||||
|
|
|
@ -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);
|
S->num_params = mysql_stmt_param_count(S->stmt);
|
||||||
|
|
||||||
if (S->num_params) {
|
if (S->num_params) {
|
||||||
S->params_given = 0;
|
|
||||||
#ifdef PDO_USE_MYSQLND
|
#ifdef PDO_USE_MYSQLND
|
||||||
S->params = NULL;
|
S->params = NULL;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -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");
|
strcpy(stmt->error_code, "HY093");
|
||||||
PDO_DBG_RETURN(0);
|
PDO_DBG_RETURN(0);
|
||||||
}
|
}
|
||||||
S->params_given++;
|
|
||||||
|
|
||||||
#ifndef PDO_USE_MYSQLND
|
#ifndef PDO_USE_MYSQLND
|
||||||
b = &S->params[param->paramno];
|
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);
|
PDO_DBG_RETURN(1);
|
||||||
|
|
||||||
case PDO_PARAM_EVT_EXEC_PRE:
|
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 */
|
/* too few parameter bound */
|
||||||
PDO_DBG_ERR("too few parameters bound");
|
PDO_DBG_ERR("too few parameters bound");
|
||||||
strcpy(stmt->error_code, "HY093");
|
strcpy(stmt->error_code, "HY093");
|
||||||
|
|
|
@ -141,7 +141,6 @@ typedef struct {
|
||||||
PDO_MYSQL_PARAM_BIND *bound_result;
|
PDO_MYSQL_PARAM_BIND *bound_result;
|
||||||
my_bool *out_null;
|
my_bool *out_null;
|
||||||
zend_ulong *out_length;
|
zend_ulong *out_length;
|
||||||
unsigned int params_given;
|
|
||||||
unsigned max_length:1;
|
unsigned max_length:1;
|
||||||
/* Whether all result sets have been fully consumed.
|
/* Whether all result sets have been fully consumed.
|
||||||
* If this flag is not set, they need to be consumed during destruction. */
|
* If this flag is not set, they need to be consumed during destruction. */
|
||||||
|
|
66
ext/pdo_mysql/tests/bug79132.phpt
Normal file
66
ext/pdo_mysql/tests/bug79132.phpt
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue