diff --git a/NEWS b/NEWS index daf52ae14d95..353307087019 100644 --- a/NEWS +++ b/NEWS @@ -233,6 +233,10 @@ PHP NEWS . Fixed a duplicate warning when ATTR_STATEMENT_CLASS is rejected on a persistent connection. (Ilia Alshanetsky) +- PDO_DBLIB: + . Fixed a crash on persistent connections after an error raised through + PDO::exec(). (Ilia Alshanetsky) + - PDO_Firebird: . Fixed bug GH-25006 (getColumnMeta() reads out of bounds for an out-of-range column index). (Ilia Alshanetsky) diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c index dd8fb1c320c6..79fe467bb1e7 100644 --- a/ext/pdo_dblib/dblib_driver.c +++ b/ext/pdo_dblib/dblib_driver.c @@ -92,6 +92,15 @@ static void dblib_handle_closer(pdo_dbh_t *dbh) } } +static void dblib_handle_request_shutdown(pdo_dbh_t *dbh) +{ + pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data; + + if (H && dbh->refcount <= 2) { + pdo_dblib_err_dtor(&H->err); + } +} + static bool dblib_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_t *stmt, zval *driver_options) { pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data; @@ -450,7 +459,7 @@ static const struct pdo_dbh_methods dblib_methods = { dblib_get_attribute, /* get attr */ NULL, /* check liveness */ NULL, /* get driver methods */ - NULL, /* request shutdown */ + dblib_handle_request_shutdown, NULL, /* in transaction, use PDO's internal tracking mechanism */ NULL, /* get gc */ NULL /* scanner */ diff --git a/ext/pdo_dblib/tests/persistent_error_state_across_requests.phpt b/ext/pdo_dblib/tests/persistent_error_state_across_requests.phpt new file mode 100644 index 000000000000..2c72db11e586 --- /dev/null +++ b/ext/pdo_dblib/tests/persistent_error_state_across_requests.phpt @@ -0,0 +1,44 @@ +--TEST-- +PDO_DBLIB: Persistent handle error state does not outlive the request +--EXTENSIONS-- +pdo_dblib +--SKIPIF-- + +--ENV-- +USE_ZEND_ALLOC=0 +USE_TRACKED_ALLOC=1 +--FILE-- + true, PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT]); +$stmt = $db->prepare('SELECT 1'); +$stmt->execute(); +var_dump($stmt->fetchColumn()); +$db->exec('SELECT * FROM ' . $_GET['table']); +echo $db->errorInfo()[2], "\n"; +PHP, var_export(__DIR__ . '/config.inc', true)); + +$args = []; +foreach (['pdo', 'pdo_dblib'] as $ext) { + if (file_exists(ini_get('extension_dir') . '/' . $ext . '.' . PHP_SHLIB_SUFFIX)) { + $args[] = '-dextension=' . ini_get('extension_dir') . '/' . $ext . '.' . PHP_SHLIB_SUFFIX; + } +} +php_cli_server_start($code, null, $args); + +foreach (['pdo_dblib_missing_first', 'pdo_dblib_missing_second'] as $table) { + echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/index.php?table=' . $table); +} +?> +--EXPECTF-- +int(1) +Invalid object name 'pdo_dblib_missing_first'. [%d] (severity %d) [] +int(1) +Invalid object name 'pdo_dblib_missing_second'. [%d] (severity %d) []