diff options
author | Xinchen Hui <laruence@gmail.com> | 2016-08-09 11:25:32 +0800 |
---|---|---|
committer | Xinchen Hui <laruence@gmail.com> | 2016-08-09 11:25:32 +0800 |
commit | ebd21de1e4d5321fb979e9ba22de623d9e24ae29 (patch) | |
tree | 1d618914cb7314ae9ae6d28632aa5a4c79c58fb2 | |
parent | 5358c7cf5eda4a4c72e232e22c2f8179f0e8007d (diff) | |
parent | a74c7cb528c47726ee998a514986663a9c6835e5 (diff) | |
download | php-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.c | 8 | ||||
-rw-r--r-- | ext/pdo/tests/bug_72788.phpt | 33 | ||||
-rw-r--r-- | ext/pdo/tests/pdo_017.phpt | 4 | ||||
-rw-r--r-- | ext/pdo_mysql/mysql_statement.c | 3 | ||||
-rw-r--r-- | ext/pdo_pgsql/pgsql_statement.c | 3 |
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) { |