mirror of
https://github.com/php/php-src.git
synced 2025-01-11 21:43:52 +08:00
Merge branch 'PHP-7.4'
This commit is contained in:
commit
98de4207d8
@ -612,7 +612,7 @@ mysqlnd_stmt_execute_prepare_param_types(MYSQLND_STMT_DATA * stmt, zval ** copie
|
||||
zval *parameter = &stmt->param_bind[i].zv;
|
||||
|
||||
ZVAL_DEREF(parameter);
|
||||
if (!Z_ISNULL_P(parameter) && (current_type == MYSQL_TYPE_LONG || current_type == MYSQL_TYPE_LONGLONG)) {
|
||||
if (!Z_ISNULL_P(parameter) && (current_type == MYSQL_TYPE_LONG || current_type == MYSQL_TYPE_LONGLONG || current_type == MYSQL_TYPE_TINY)) {
|
||||
/* always copy the var, because we do many conversions */
|
||||
if (Z_TYPE_P(parameter) != IS_LONG &&
|
||||
PASS != mysqlnd_stmt_copy_it(copies_param, parameter, stmt->param_count, i))
|
||||
@ -828,6 +828,13 @@ mysqlnd_stmt_execute_store_param_values(MYSQLND_STMT_DATA * stmt, zval * copies,
|
||||
int4store(*p, Z_LVAL_P(data));
|
||||
(*p) += 4;
|
||||
break;
|
||||
case MYSQL_TYPE_TINY:
|
||||
if (Z_TYPE_P(data) == IS_STRING) {
|
||||
goto send_string;
|
||||
}
|
||||
int1store(*p, Z_LVAL_P(data));
|
||||
(*p)++;
|
||||
break;
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
if (stmt->param_bind[i].flags & MYSQLND_PARAM_BIND_BLOB_USED) {
|
||||
stmt->param_bind[i].flags &= ~MYSQLND_PARAM_BIND_BLOB_USED;
|
||||
|
@ -558,6 +558,10 @@ static int pdo_mysql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_da
|
||||
mysqlnd_stmt_bind_one_param(S->stmt, param->paramno, parameter, MYSQL_TYPE_LONG);
|
||||
#endif /* SIZEOF_LONG */
|
||||
break;
|
||||
case IS_TRUE:
|
||||
case IS_FALSE:
|
||||
mysqlnd_stmt_bind_one_param(S->stmt, param->paramno, parameter, MYSQL_TYPE_TINY);
|
||||
break;
|
||||
case IS_DOUBLE:
|
||||
mysqlnd_stmt_bind_one_param(S->stmt, param->paramno, parameter, MYSQL_TYPE_DOUBLE);
|
||||
break;
|
||||
|
282
ext/pdo_mysql/tests/bug_38546.phpt
Normal file
282
ext/pdo_mysql/tests/bug_38546.phpt
Normal file
@ -0,0 +1,282 @@
|
||||
--TEST--
|
||||
PDO MySQL Bug #38546 (bindParam incorrect processing of bool types)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
||||
|
||||
$db->exec("DROP TABLE IF EXISTS test");
|
||||
|
||||
$query = "CREATE TABLE test(
|
||||
uid MEDIUMINT UNSIGNED NOT NULL,
|
||||
some_bool_1 BOOL NOT NULL,
|
||||
some_bool_2 BOOL NOT NULL,
|
||||
some_int TINYINT NOT NULL
|
||||
)";
|
||||
$db->exec($query);
|
||||
|
||||
$st = $db->prepare("INSERT INTO test (uid, some_bool_1, some_bool_2, some_int) VALUES (?, ?, ?, ?)");
|
||||
|
||||
$values = [
|
||||
'uid' => 6,
|
||||
'some_bool_1' => false,
|
||||
'some_bool_2' => true,
|
||||
'some_int' => -23
|
||||
];
|
||||
$st->bindParam(1, $values['uid'], PDO::PARAM_INT);
|
||||
$st->bindParam(2, $values['some_bool_1'], PDO::PARAM_BOOL);
|
||||
$st->bindParam(3, $values['some_bool_2'], PDO::PARAM_BOOL);
|
||||
$st->bindParam(4, $values['some_int'], PDO::PARAM_INT);
|
||||
|
||||
$result = $st->execute();
|
||||
|
||||
if ($result === false) {
|
||||
var_dump($st->errorInfo());
|
||||
} else {
|
||||
print("ok insert\n");
|
||||
}
|
||||
|
||||
foreach ($db->query('SELECT * from test') as $row) {
|
||||
print_r($row);
|
||||
}
|
||||
|
||||
$st = $db->prepare("UPDATE test SET some_bool_1=?, some_bool_2=?, some_int=? WHERE uid=?");
|
||||
|
||||
$values = [
|
||||
'uid' => 6,
|
||||
'some_bool_1' => (bool) 1,
|
||||
'some_bool_2' => (bool) 0,
|
||||
'some_int' => 1,
|
||||
];
|
||||
|
||||
$st->bindParam(1, $values['some_bool_1'], PDO::PARAM_BOOL);
|
||||
$st->bindParam(2, $values['some_bool_2'], PDO::PARAM_BOOL);
|
||||
$st->bindParam(3, $values['some_int'], PDO::PARAM_INT);
|
||||
$st->bindParam(4, $values['uid'], PDO::PARAM_INT);
|
||||
|
||||
$result = $st->execute();
|
||||
|
||||
if ($result === false) {
|
||||
var_dump($st->errorInfo());
|
||||
} else {
|
||||
print("ok prepare 1\n");
|
||||
}
|
||||
|
||||
foreach ($db->query('SELECT * from test') as $row) {
|
||||
print_r($row);
|
||||
}
|
||||
|
||||
$st = $db->prepare("UPDATE test SET some_bool_1=?, some_bool_2=?, some_int=? WHERE uid=?");
|
||||
|
||||
$values = [
|
||||
'uid' => 6,
|
||||
'some_bool_1' => (bool) 0,
|
||||
'some_bool_2' => (bool) 1,
|
||||
'some_int' => 2,
|
||||
];
|
||||
|
||||
$st->bindParam(1, $values['some_bool_1'], PDO::PARAM_BOOL);
|
||||
$st->bindParam(2, $values['some_bool_2'], PDO::PARAM_BOOL);
|
||||
$st->bindParam(3, $values['some_int'], PDO::PARAM_INT);
|
||||
$st->bindParam(4, $values['uid'], PDO::PARAM_INT);
|
||||
|
||||
$result = $st->execute();
|
||||
|
||||
if ($result === false) {
|
||||
var_dump($st->errorInfo());
|
||||
} else {
|
||||
print("ok prepare 2\n");
|
||||
}
|
||||
|
||||
foreach ($db->query('SELECT * from test') as $row) {
|
||||
print_r($row);
|
||||
}
|
||||
|
||||
// String true and false should fail
|
||||
$st = $db->prepare("UPDATE test SET some_bool_1=?, some_bool_2=?, some_int=? WHERE uid=?");
|
||||
|
||||
$values = [
|
||||
'uid' => 6,
|
||||
'some_bool_1' => 'true',
|
||||
'some_bool_2' => 'false',
|
||||
'some_int' => 3,
|
||||
];
|
||||
|
||||
$st->bindParam(1, $values['some_bool_1'], PDO::PARAM_BOOL);
|
||||
$st->bindParam(2, $values['some_bool_2'], PDO::PARAM_BOOL);
|
||||
$st->bindParam(3, $values['some_int'], PDO::PARAM_INT);
|
||||
$st->bindParam(4, $values['uid'], PDO::PARAM_INT);
|
||||
|
||||
$result = $st->execute();
|
||||
|
||||
if ($result === false) {
|
||||
var_dump($st->errorInfo());
|
||||
} else {
|
||||
print("ok prepare 3\n");
|
||||
}
|
||||
|
||||
foreach ($db->query('SELECT * from test') as $row) {
|
||||
print_r($row);
|
||||
}
|
||||
|
||||
// Null should not be treated as false
|
||||
$st = $db->prepare("UPDATE test SET some_bool_1=?, some_bool_2=?, some_int=? WHERE uid=?");
|
||||
|
||||
$values = [
|
||||
'uid' => 6,
|
||||
'some_bool_1' => true,
|
||||
'some_bool_2' => null,
|
||||
'some_int' => 4,
|
||||
];
|
||||
|
||||
$st->bindParam(1, $values['some_bool_1'], PDO::PARAM_BOOL);
|
||||
$st->bindParam(2, $values['some_bool_2'], PDO::PARAM_BOOL);
|
||||
$st->bindParam(3, $values['some_int'], PDO::PARAM_INT);
|
||||
$st->bindParam(4, $values['uid'], PDO::PARAM_INT);
|
||||
|
||||
$result = $st->execute();
|
||||
|
||||
if ($result === false) {
|
||||
var_dump($st->errorInfo());
|
||||
} else {
|
||||
print("ok prepare 4\n");
|
||||
}
|
||||
|
||||
foreach ($db->query('SELECT * from test') as $row) {
|
||||
print_r($row);
|
||||
}
|
||||
|
||||
// Integers converted correctly
|
||||
$st = $db->prepare("UPDATE test SET some_bool_1=?, some_bool_2=?, some_int=? WHERE uid=?");
|
||||
|
||||
$values = [
|
||||
'uid' => 6,
|
||||
'some_bool_1' => 256,
|
||||
'some_bool_2' => 0,
|
||||
'some_int' => 5,
|
||||
];
|
||||
|
||||
$st->bindParam(1, $values['some_bool_1'], PDO::PARAM_BOOL);
|
||||
$st->bindParam(2, $values['some_bool_2'], PDO::PARAM_BOOL);
|
||||
$st->bindParam(3, $values['some_int'], PDO::PARAM_INT);
|
||||
$st->bindParam(4, $values['uid'], PDO::PARAM_INT);
|
||||
|
||||
$result = $st->execute();
|
||||
|
||||
if ($result === false) {
|
||||
var_dump($st->errorInfo());
|
||||
} else {
|
||||
print("ok prepare 5\n");
|
||||
}
|
||||
|
||||
foreach ($db->query('SELECT * from test') as $row) {
|
||||
print_r($row);
|
||||
}
|
||||
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require dirname(__FILE__) . '/mysql_pdo_test.inc';
|
||||
MySQLPDOTest::dropTestTable();
|
||||
?>
|
||||
--EXPECTF--
|
||||
ok insert
|
||||
Array
|
||||
(
|
||||
[uid] => 6
|
||||
[0] => 6
|
||||
[some_bool_1] => 0
|
||||
[1] => 0
|
||||
[some_bool_2] => 1
|
||||
[2] => 1
|
||||
[some_int] => -23
|
||||
[3] => -23
|
||||
)
|
||||
ok prepare 1
|
||||
Array
|
||||
(
|
||||
[uid] => 6
|
||||
[0] => 6
|
||||
[some_bool_1] => 1
|
||||
[1] => 1
|
||||
[some_bool_2] => 0
|
||||
[2] => 0
|
||||
[some_int] => 1
|
||||
[3] => 1
|
||||
)
|
||||
ok prepare 2
|
||||
Array
|
||||
(
|
||||
[uid] => 6
|
||||
[0] => 6
|
||||
[some_bool_1] => 0
|
||||
[1] => 0
|
||||
[some_bool_2] => 1
|
||||
[2] => 1
|
||||
[some_int] => 2
|
||||
[3] => 2
|
||||
)
|
||||
|
||||
Warning: PDOStatement::execute(): SQLSTATE[HY000]: General error: 1366 Incorrect integer value: 'true' for column 'some_bool_1' at row 1 in %s
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(5) "HY000"
|
||||
[1]=>
|
||||
int(1366)
|
||||
[2]=>
|
||||
string(65) "Incorrect integer value: 'true' for column 'some_bool_1' at row 1"
|
||||
}
|
||||
Array
|
||||
(
|
||||
[uid] => 6
|
||||
[0] => 6
|
||||
[some_bool_1] => 0
|
||||
[1] => 0
|
||||
[some_bool_2] => 1
|
||||
[2] => 1
|
||||
[some_int] => 2
|
||||
[3] => 2
|
||||
)
|
||||
|
||||
Warning: PDOStatement::execute(): SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'some_bool_2' cannot be null in %s
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(5) "23000"
|
||||
[1]=>
|
||||
int(1048)
|
||||
[2]=>
|
||||
string(35) "Column 'some_bool_2' cannot be null"
|
||||
}
|
||||
Array
|
||||
(
|
||||
[uid] => 6
|
||||
[0] => 6
|
||||
[some_bool_1] => 0
|
||||
[1] => 0
|
||||
[some_bool_2] => 1
|
||||
[2] => 1
|
||||
[some_int] => 2
|
||||
[3] => 2
|
||||
)
|
||||
ok prepare 5
|
||||
Array
|
||||
(
|
||||
[uid] => 6
|
||||
[0] => 6
|
||||
[some_bool_1] => 1
|
||||
[1] => 1
|
||||
[some_bool_2] => 0
|
||||
[2] => 0
|
||||
[some_int] => 5
|
||||
[3] => 5
|
||||
)
|
@ -37,8 +37,6 @@ function bug_44707($db) {
|
||||
|
||||
$stmt = $db->prepare('INSERT INTO test(id, mybool) VALUES (?, ?)');
|
||||
$stmt->bindParam(1, $id);
|
||||
// From MySQL 4.1 on boolean and TINYINT don't match! INSERT will fail.
|
||||
// Versions prior to 4.1 have a weak test and will accept this.
|
||||
$stmt->bindParam(2, $mybool, PDO::PARAM_BOOL);
|
||||
var_dump($mybool);
|
||||
|
||||
@ -78,8 +76,6 @@ Native Prepared Statements
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
array(0) {
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
@ -89,4 +85,20 @@ array(1) {
|
||||
string(1) "0"
|
||||
}
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["mybool"]=>
|
||||
string(1) "0"
|
||||
}
|
||||
[1]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["mybool"]=>
|
||||
string(1) "0"
|
||||
}
|
||||
}
|
||||
done!
|
||||
|
Loading…
Reference in New Issue
Block a user