mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Merge branch 'PHP-8.4'
* PHP-8.4: Fix GH-19706: dba stream resource mismanagement
This commit is contained in:
@@ -256,14 +256,14 @@ static void dba_close_info(dba_info *info)
|
||||
if (info->flags & DBA_PERSISTENT) {
|
||||
php_stream_pclose(info->fp);
|
||||
} else {
|
||||
php_stream_close(info->fp);
|
||||
php_stream_free(info->fp, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR);
|
||||
}
|
||||
}
|
||||
if (info->lock.fp) {
|
||||
if (info->flags & DBA_PERSISTENT) {
|
||||
php_stream_pclose(info->lock.fp);
|
||||
} else {
|
||||
php_stream_close(info->lock.fp);
|
||||
php_stream_free(info->lock.fp, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -516,6 +516,17 @@ static zend_always_inline zend_string *php_dba_zend_string_dup_safe(zend_string
|
||||
}
|
||||
}
|
||||
|
||||
/* See mysqlnd_fixup_regular_list */
|
||||
static void php_dba_fixup_regular_list(php_stream *stream)
|
||||
{
|
||||
dtor_func_t origin_dtor = EG(regular_list).pDestructor;
|
||||
EG(regular_list).pDestructor = NULL;
|
||||
zend_hash_index_del(&EG(regular_list), stream->res->handle);
|
||||
EG(regular_list).pDestructor = origin_dtor;
|
||||
efree(stream->res);
|
||||
stream->res = NULL;
|
||||
}
|
||||
|
||||
/* {{{ php_dba_open */
|
||||
static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent)
|
||||
{
|
||||
@@ -827,6 +838,9 @@ restart:
|
||||
/* do not log errors for .lck file while in read only mode on .lck file */
|
||||
lock_file_mode = "rb";
|
||||
connection->info->lock.fp = php_stream_open_wrapper(lock_name, lock_file_mode, STREAM_MUST_SEEK|IGNORE_PATH|persistent_flag, NULL);
|
||||
if (connection->info->lock.fp && !persistent_flag) {
|
||||
php_dba_fixup_regular_list(connection->info->lock.fp);
|
||||
}
|
||||
}
|
||||
if (!connection->info->lock.fp) {
|
||||
/* when not in read mode or failed to open .lck file read only. now try again in create(write) mode and log errors */
|
||||
@@ -837,6 +851,9 @@ restart:
|
||||
zend_string *opened_path = NULL;
|
||||
connection->info->lock.fp = php_stream_open_wrapper(lock_name, lock_file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|persistent_flag, &opened_path);
|
||||
if (connection->info->lock.fp) {
|
||||
if (!persistent_flag) {
|
||||
php_dba_fixup_regular_list(connection->info->lock.fp);
|
||||
}
|
||||
if (is_db_lock) {
|
||||
if (opened_path) {
|
||||
/* replace the path info with the real path of the opened file */
|
||||
@@ -873,6 +890,9 @@ restart:
|
||||
connection->info->fp = connection->info->lock.fp; /* use the same stream for locking and database access */
|
||||
} else {
|
||||
connection->info->fp = php_stream_open_wrapper(ZSTR_VAL(connection->info->path), file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|persistent_flag, NULL);
|
||||
if (connection->info->fp && !persistent_flag) {
|
||||
php_dba_fixup_regular_list(connection->info->fp);
|
||||
}
|
||||
}
|
||||
if (!connection->info->fp) {
|
||||
/* stream operation already wrote an error message */
|
||||
|
||||
20
ext/dba/tests/gh19706.phpt
Normal file
20
ext/dba/tests/gh19706.phpt
Normal file
@@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
GH-19706 (dba stream resource mismanagement)
|
||||
--EXTENSIONS--
|
||||
dba
|
||||
--FILE--
|
||||
<?php
|
||||
// Must be in the global scope such that it's part of the symbol table cleanup
|
||||
$db = dba_open(__DIR__ . '/gh19706.cdb', 'n', 'cdb_make');
|
||||
$db2 = $db;
|
||||
var_dump($db, $db2);
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
@unlink(__DIR__ . '/gh19706.cdb');
|
||||
?>
|
||||
--EXPECT--
|
||||
object(Dba\Connection)#1 (0) {
|
||||
}
|
||||
object(Dba\Connection)#1 (0) {
|
||||
}
|
||||
Reference in New Issue
Block a user