]> granicus.if.org Git - php/commitdiff
Fixed bug #77289
authorLauri Kenttä <lauri.kentta@gmail.com>
Wed, 9 Jan 2019 08:50:26 +0000 (09:50 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 9 Jan 2019 08:50:26 +0000 (09:50 +0100)
Use mysqlnd_restart_psession and mysqlnd_end_psession in PDO MySQL.
This makes sure we free last_message while ZMM is still live.

NEWS
ext/pdo_mysql/mysql_driver.c
ext/pdo_mysql/tests/bug77289.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 48566bb35760f07a7219a1ee9957dd68756f5bf3..7d9a45223a5173716f0d58946e4cadc9c4bbc239 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -54,6 +54,10 @@ PHP                                                                        NEWS
   . Fixed bug #77273 (array_walk_recursive corrupts value types leading to PDO
     failure). (Nikita)
 
+- PDO MySQL:
+  . Fixed bug #77289 (PDO MySQL segfaults with persistent connection).
+    (Lauri Kenttä)
+
 - Phar:
   . Fixed bug #77247 (heap buffer overflow in phar_detect_phar_fname_ext). (Stas)
 
index 2cec3daa422060b77e2059bcd71385646fa1e545..eb3473f11e737cef6488985865f9c48470e6c6f8 100644 (file)
@@ -509,6 +509,21 @@ static int pdo_mysql_check_liveness(pdo_dbh_t *dbh)
 }
 /* }}} */
 
+/* {{{ pdo_mysql_request_shutdown */
+static void pdo_mysql_request_shutdown(pdo_dbh_t *dbh)
+{
+       pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
+
+       PDO_DBG_ENTER("pdo_mysql_request_shutdown");
+       PDO_DBG_INF_FMT("dbh=%p", dbh);
+#ifdef PDO_USE_MYSQLND
+       if (H->server) {
+               mysqlnd_end_psession(H->server);
+       }
+#endif
+}
+/* }}} */
+
 /* {{{ mysql_methods */
 static const struct pdo_dbh_methods mysql_methods = {
        mysql_handle_closer,
@@ -524,7 +539,7 @@ static const struct pdo_dbh_methods mysql_methods = {
        pdo_mysql_get_attribute,
        pdo_mysql_check_liveness,
        NULL,
-       NULL,
+       pdo_mysql_request_shutdown,
        NULL
 };
 /* }}} */
@@ -589,6 +604,11 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
                pdo_mysql_error(dbh);
                goto cleanup;
        }
+#if defined(PDO_USE_MYSQLND)
+       if (dbh->is_persistent) {
+               mysqlnd_restart_psession(H->server);
+       }
+#endif
 
        dbh->driver_data = H;
 
diff --git a/ext/pdo_mysql/tests/bug77289.phpt b/ext/pdo_mysql/tests/bug77289.phpt
new file mode 100644 (file)
index 0000000..db67524
--- /dev/null
@@ -0,0 +1,24 @@
+--TEST--
+Bug #77289: PDO MySQL segfaults with persistent connection
+--SKIPIF--
+<?php
+require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
+require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
+MySQLPDOTest::skip();
+?>
+--FILE--
+<?php
+require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
+
+$dsn = MySQLPDOTest::getDSN();
+$user = PDO_MYSQL_TEST_USER;
+$pass = PDO_MYSQL_TEST_PASS;
+$pdo = new PDO($dsn, $user, $pass, [PDO::ATTR_PERSISTENT => true]);
+$pdo->exec("DROP TABLE IF EXISTS bug77289");
+$pdo->exec("CREATE TEMPORARY TABLE bug77289 (x INT)");
+$pdo->exec("UPDATE bug77289 SET x = x");
+
+?>
+===DONE===
+--EXPECT--
+===DONE===