diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-06-07 09:49:22 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-06-07 09:49:22 +0200 |
commit | 98de4207d8ce4c3ff892248816e29998b3c3c39f (patch) | |
tree | 58d4aa78f55e1fff1bb6398757ca6907d1dba266 | |
parent | 590ecaa2ff58f089f815d4b26111a7fb3f4b5bdc (diff) | |
parent | 1c4e93e8bd2baba505c13083e471363df626b4c2 (diff) | |
download | php-git-98de4207d8ce4c3ff892248816e29998b3c3c39f.tar.gz |
Merge branch 'PHP-7.4'
-rw-r--r-- | ext/mysqlnd/mysqlnd_ps_codec.c | 9 | ||||
-rw-r--r-- | ext/pdo_mysql/mysql_statement.c | 4 | ||||
-rw-r--r-- | ext/pdo_mysql/tests/bug_38546.phpt | 282 | ||||
-rw-r--r-- | ext/pdo_mysql/tests/bug_44707.phpt | 20 |
4 files changed, 310 insertions, 5 deletions
diff --git a/ext/mysqlnd/mysqlnd_ps_codec.c b/ext/mysqlnd/mysqlnd_ps_codec.c index 7da46a90f8..940bcf7ec3 100644 --- a/ext/mysqlnd/mysqlnd_ps_codec.c +++ b/ext/mysqlnd/mysqlnd_ps_codec.c @@ -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; diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c index a16324aa18..9b880ea1fa 100644 --- a/ext/pdo_mysql/mysql_statement.c +++ b/ext/pdo_mysql/mysql_statement.c @@ -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; diff --git a/ext/pdo_mysql/tests/bug_38546.phpt b/ext/pdo_mysql/tests/bug_38546.phpt new file mode 100644 index 0000000000..962a404fc0 --- /dev/null +++ b/ext/pdo_mysql/tests/bug_38546.phpt @@ -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 +)
\ No newline at end of file diff --git a/ext/pdo_mysql/tests/bug_44707.phpt b/ext/pdo_mysql/tests/bug_44707.phpt index 025b92e1fc..06979b8164 100644 --- a/ext/pdo_mysql/tests/bug_44707.phpt +++ b/ext/pdo_mysql/tests/bug_44707.phpt @@ -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! |