summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@gmail.com>2016-08-09 11:25:32 +0800
committerXinchen Hui <laruence@gmail.com>2016-08-09 11:25:32 +0800
commitebd21de1e4d5321fb979e9ba22de623d9e24ae29 (patch)
tree1d618914cb7314ae9ae6d28632aa5a4c79c58fb2
parent5358c7cf5eda4a4c72e232e22c2f8179f0e8007d (diff)
parenta74c7cb528c47726ee998a514986663a9c6835e5 (diff)
downloadphp-git-ebd21de1e4d5321fb979e9ba22de623d9e24ae29.tar.gz
Merge branch 'bug72788' of https://github.com/keyurdg/php-src into PHP-7.0
* 'bug72788' of https://github.com/keyurdg/php-src: Remove typo'd commit Fix bug 72788: Invalid memory access when database_object_handle is undefined. Also fix memory leak in dbh_free when using persistent PDO connections.
-rw-r--r--ext/pdo/pdo_dbh.c8
-rw-r--r--ext/pdo/tests/bug_72788.phpt33
-rw-r--r--ext/pdo/tests/pdo_017.phpt4
-rw-r--r--ext/pdo_mysql/mysql_statement.c3
-rw-r--r--ext/pdo_pgsql/pgsql_statement.c3
5 files changed, 43 insertions, 8 deletions
diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c
index 2fb5334a9d..8a7c1d3931 100644
--- a/ext/pdo/pdo_dbh.c
+++ b/ext/pdo/pdo_dbh.c
@@ -1503,15 +1503,15 @@ static void dbh_free(pdo_dbh_t *dbh, zend_bool free_persistent)
{
int i;
- if (dbh->is_persistent && !free_persistent) {
- return;
- }
-
if (dbh->query_stmt) {
zval_ptr_dtor(&dbh->query_stmt_zval);
dbh->query_stmt = NULL;
}
+ if (dbh->is_persistent && !free_persistent) {
+ return;
+ }
+
if (dbh->methods) {
dbh->methods->closer(dbh);
}
diff --git a/ext/pdo/tests/bug_72788.phpt b/ext/pdo/tests/bug_72788.phpt
new file mode 100644
index 0000000000..80609a21ba
--- /dev/null
+++ b/ext/pdo/tests/bug_72788.phpt
@@ -0,0 +1,33 @@
+--TEST--
+PDO Common: Bug #72788 (Invalid memory access when using persistent PDO connection)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+
+putenv("PDOTEST_ATTR=" . serialize(array(PDO::ATTR_PERSISTENT => true)));
+
+function test() {
+ $db = PDOTest::factory('PDO', false);
+ $stmt = @$db->query("SELECT 1 FROM TABLE_DOES_NOT_EXIST");
+ if ($stmt === false) {
+ echo "Statement failed as expected\n";
+ }
+}
+
+test();
+test();
+echo "Done";
+?>
+--EXPECT--
+Statement failed as expected
+Statement failed as expected
+Done
diff --git a/ext/pdo/tests/pdo_017.phpt b/ext/pdo/tests/pdo_017.phpt
index 31ee88b76b..2b8568fb46 100644
--- a/ext/pdo/tests/pdo_017.phpt
+++ b/ext/pdo/tests/pdo_017.phpt
@@ -16,7 +16,7 @@ try {
}
if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {
- require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
+ require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../../pdo_mysql/tests/mysql_pdo_test.inc');
if (false === MySQLPDOTest::detect_transactional_mysql_engine($db)) {
die('skip your mysql configuration does not support working transactions');
}
@@ -29,7 +29,7 @@ require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
$db = PDOTest::factory();
if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {
- require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
+ require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../../pdo_mysql/tests/mysql_pdo_test.inc');
$suf = ' ENGINE=' . MySQLPDOTest::detect_transactional_mysql_engine($db);
} else {
$suf = '';
diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c
index b141de79ef..4a2146dd16 100644
--- a/ext/pdo_mysql/mysql_statement.c
+++ b/ext/pdo_mysql/mysql_statement.c
@@ -88,7 +88,8 @@ static int pdo_mysql_stmt_dtor(pdo_stmt_t *stmt) /* {{{ */
}
#endif
- if (IS_OBJ_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE(stmt->database_object_handle)])
+ if (!Z_ISUNDEF(stmt->database_object_handle)
+ && IS_OBJ_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE(stmt->database_object_handle)])
&& (!(GC_FLAGS(Z_OBJ(stmt->database_object_handle)) & IS_OBJ_FREE_CALLED))) {
while (mysql_more_results(S->H->server)) {
MYSQL_RES *res;
diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c
index a5ee2e993e..f7c46a6706 100644
--- a/ext/pdo_pgsql/pgsql_statement.c
+++ b/ext/pdo_pgsql/pgsql_statement.c
@@ -61,7 +61,8 @@
static int pgsql_stmt_dtor(pdo_stmt_t *stmt)
{
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
- zend_bool server_obj_usable = IS_OBJ_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE(stmt->database_object_handle)])
+ zend_bool server_obj_usable = !Z_ISUNDEF(stmt->database_object_handle)
+ && IS_OBJ_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE(stmt->database_object_handle)])
&& !(GC_FLAGS(Z_OBJ(stmt->database_object_handle)) & IS_OBJ_FREE_CALLED);
if (S->result) {