]> granicus.if.org Git - php/commitdiff
Fixed bug #79131
authorNikita Popov <nikita.ppv@gmail.com>
Thu, 10 Dec 2020 14:51:17 +0000 (15:51 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Thu, 10 Dec 2020 14:53:23 +0000 (15:53 +0100)
When a driver reports an error during EVT_ALLOC (and some over EVTs),
make sure we handle it as usual, i.e. warn or throw.

This requires some adjustments in PDO PgSQL to stop manually doing
this through an impl error.

Unfortunately the PDO PgSQL error messages regress because of this,
as they now include a completely arbitrary error code. There doesn't
seem to be an ability to skip it right now.

NEWS
ext/pdo/pdo_stmt.c
ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_anonymous.phpt
ext/pdo_mysql/tests/pdo_mysql_prepare_native_named_placeholder.phpt
ext/pdo_pgsql/pgsql_statement.c
ext/pdo_pgsql/php_pdo_pgsql_int.h
ext/pdo_pgsql/tests/bug36727.phpt
ext/pdo_pgsql/tests/bug69344.phpt
ext/pdo_pgsql/tests/bug71573.phpt

diff --git a/NEWS b/NEWS
index 0a91136d7636375b94d8235518c70f187c222914..536b028fd9b0b2105c4ba61c86dad6d295c644fa 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -52,6 +52,8 @@ PHP                                                                        NEWS
   . Fixed bug #76815 (PDOStatement cannot be GCed/closeCursor-ed when a
     PROCEDURE resultset SIGNAL). (Nikita)
   . Fixed bug #79872 (Can't execute query with pending result sets). (Nikita)
+  . Fixed bug #79131 (PDO does not throw an exception when parameter values are
+    missing). (Nikita)
 
 - Phar:
   . Fixed bug #73809 (Phar Zip parse crash - mmap fail). (cmb)
index d4c60866904ae4e628fd45e6da1c2cf8df10ebe0..68ec99160a65249251d4efcdb4e55041a88f3512 100644 (file)
@@ -341,8 +341,8 @@ static bool really_register_bound_param(struct pdo_bound_param_data *param, pdo_
         * a reference to param, as it resides in transient storage only
         * at this time. */
        if (stmt->methods->param_hook) {
-               if (!stmt->methods->param_hook(stmt, param, PDO_PARAM_EVT_NORMALIZE
-                               )) {
+               if (!stmt->methods->param_hook(stmt, param, PDO_PARAM_EVT_NORMALIZE)) {
+                       PDO_HANDLE_STMT_ERR();
                        if (param->name) {
                                zend_string_release_ex(param->name, 0);
                                param->name = NULL;
@@ -367,8 +367,8 @@ static bool really_register_bound_param(struct pdo_bound_param_data *param, pdo_
 
        /* tell the driver we just created a parameter */
        if (stmt->methods->param_hook) {
-               if (!stmt->methods->param_hook(stmt, pparam, PDO_PARAM_EVT_ALLOC
-                                       )) {
+               if (!stmt->methods->param_hook(stmt, pparam, PDO_PARAM_EVT_ALLOC)) {
+                       PDO_HANDLE_STMT_ERR();
                        /* undo storage allocation; the hash will free the parameter
                         * name if required */
                        if (pparam->name) {
@@ -479,6 +479,7 @@ PHP_METHOD(PDOStatement, execute)
                }
 
                if (ret && !dispatch_param_event(stmt, PDO_PARAM_EVT_EXEC_POST)) {
+                       PDO_HANDLE_STMT_ERR();
                        RETURN_FALSE;
                }
 
index abd2615ce89f8a8a35585aa3b1e7aaa2d5b7283e..5d403c0caac96b6531656ac291909208bc036b6a 100644 (file)
@@ -64,7 +64,7 @@ require __DIR__ . '/mysql_pdo_test.inc';
 $db = MySQLPDOTest::factory();
 $db->exec('DROP TABLE IF EXISTS test');
 ?>
---EXPECT--
+--EXPECTF--
 array(1) {
   [0]=>
   array(2) {
@@ -75,6 +75,8 @@ array(1) {
   }
 }
 now the same with native PS
+
+Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number in %s on line %d
 [005] Execute has failed, 'HY093' array (
   0 => 'HY093',
   1 => NULL,
index 6b553375d630b12b1955507cef10e04abd6be5b5..ea4d097809d43e101d3ff2ff0b96c4b42df72063 100644 (file)
@@ -72,7 +72,8 @@ require __DIR__ . '/mysql_pdo_test.inc';
 $db = MySQLPDOTest::factory();
 $db->exec('DROP TABLE IF EXISTS test');
 ?>
---EXPECT--
+--EXPECTF--
+Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number in %s on line %d
 [003] Execute has failed, 'HY093' array (
   0 => 'HY093',
   1 => NULL,
index 88031622a438417d62b010400c33e1c4cca17e5a..149e1e6b51e0b8c9fd962ac28e49911d0ef47cec 100644 (file)
@@ -282,7 +282,8 @@ static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *
                                                        ZEND_ATOL(param->paramno, namevar + 1);
                                                        param->paramno--;
                                                } else {
-                                                       pdo_raise_impl_error(stmt->dbh, stmt, "HY093", ZSTR_VAL(param->name));
+                                                       pdo_pgsql_error_stmt_msg(
+                                                               stmt, PGRES_FATAL_ERROR, "HY093", ZSTR_VAL(param->name));
                                                        return 0;
                                                }
                                        }
@@ -294,7 +295,8 @@ static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *
                                        return 1;
                                }
                                if (!zend_hash_index_exists(stmt->bound_param_map, param->paramno)) {
-                                       pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined");
+                                       pdo_pgsql_error_stmt_msg(
+                                               stmt, PGRES_FATAL_ERROR, "HY093", "parameter was not defined");
                                        return 0;
                                }
                        case PDO_PARAM_EVT_EXEC_POST:
index 07dfa8ce2761123ecf8bc949a934d214b43416ad..bc31c9cdeee0f094ca108a728883ad947cb29030 100644 (file)
@@ -79,7 +79,8 @@ extern int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const
 #define pdo_pgsql_error(d,e,z) _pdo_pgsql_error(d, NULL, e, z, NULL, __FILE__, __LINE__)
 #define pdo_pgsql_error_msg(d,e,m)     _pdo_pgsql_error(d, NULL, e, NULL, m, __FILE__, __LINE__)
 #define pdo_pgsql_error_stmt(s,e,z)    _pdo_pgsql_error(s->dbh, s, e, z, NULL, __FILE__, __LINE__)
-#define pdo_pgsql_error_stmt_msg(s,e,m)        _pdo_pgsql_error(s->dbh, s, e, NULL, m, __FILE__, __LINE__)
+#define pdo_pgsql_error_stmt_msg(stmt, e, sqlstate, msg) \
+       _pdo_pgsql_error(stmt->dbh, stmt, e, sqlstate, msg, __FILE__, __LINE__)
 
 extern const struct pdo_stmt_methods pgsql_stmt_methods;
 
index e6b5ab7f283dd23c22f50579b11dcfdfabd92ef2..4c9716d14152b478eb714483e11182db5b25765b 100644 (file)
@@ -19,6 +19,6 @@ var_dump($stmt->bindValue(':test', 1, PDO::PARAM_INT));
 echo "Done\n";
 ?>
 --EXPECTF--
-Warning: PDOStatement::bindValue(): SQLSTATE[HY093]: Invalid parameter number: :test in %sbug36727.php on line %d
+Warning: PDOStatement::bindValue(): SQLSTATE[HY093]: Invalid parameter number: 7 :test in %s on line %d
 bool(false)
 Done
index f544518455f2f23e1f1e7e66d6abd4c923c565c8..e2522653f500dad8e8e680347569a3ce7e1960ef 100644 (file)
@@ -39,5 +39,5 @@ $test();
 
 ?>
 --EXPECT--
-SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
+SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
 SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
index 66562344ef3478895a88fb5a1c30cbe1ebdc6cfc..d9e4fe751436a6f48c2b2aa3241675a5925b0004 100644 (file)
@@ -18,4 +18,4 @@ $statement->execute([ 'test', 'test', 'test' ]);
 
 ?>
 --EXPECTF--
-Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in %sbug71573.php on line %d
+Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: 7 parameter was not defined in %s on line %d