1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Merge branch 'PHP-8.4' into PHP-8.5

* PHP-8.4:
  phar: Fix SplFileInfo::openFile() in write mode
This commit is contained in:
Niels Dossche
2025-12-21 13:18:39 +01:00
8 changed files with 52 additions and 11 deletions

1
NEWS
View File

@@ -33,6 +33,7 @@ PHP NEWS
- Phar:
. Fixed bug GH-20732 (Phar::LoadPhar undefined behavior when reading fails).
(ndossche)
. Fix SplFileInfo::openFile() in write mode. (ndossche)
- Sqlite3:
. Fixed bug GH-20699 (SQLite3Result fetchArray return array|false,

View File

@@ -420,7 +420,7 @@ void phar_entry_remove(phar_entry_data *idata, char **error) /* {{{ */
phar = idata->phar;
if (idata->internal_file->fp_refcount < 2) {
if (idata->internal_file->fp_refcount < 2 && idata->internal_file->fileinfo_lock_count == 0) {
if (idata->fp && idata->fp != idata->phar->fp && idata->fp != idata->phar->ufp && idata->fp != idata->internal_file->fp) {
php_stream_close(idata->fp);
}

View File

@@ -215,6 +215,7 @@ typedef struct _phar_entry_info {
php_stream *fp;
php_stream *cfp;
int fp_refcount;
unsigned int fileinfo_lock_count;
char *tmp;
phar_archive_data *phar;
char *link; /* symbolic link to another file */

View File

@@ -4513,7 +4513,7 @@ PHP_METHOD(PharFileInfo, __construct)
entry_obj->entry = entry_info;
if (!entry_info->is_persistent && !entry_info->is_temp_dir) {
++entry_info->fp_refcount;
++entry_info->fileinfo_lock_count;
/* The phar data must exist to keep the alias locked. */
ZEND_ASSERT(!phar_data->is_persistent);
++phar_data->refcount;
@@ -4561,7 +4561,7 @@ PHP_METHOD(PharFileInfo, __destruct)
efree(entry);
entry_obj->entry = NULL;
} else if (!entry->is_persistent) {
--entry->fp_refcount;
--entry->fileinfo_lock_count;
/* The entry itself still lives in the manifest,
* which will either be freed here if the file info was the last reference; or freed later. */
entry_obj->entry = NULL;

View File

@@ -730,7 +730,7 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /*
}
if (entry->is_deleted) {
if (entry->fp_refcount <= 0) {
if (entry->fp_refcount <= 0 && entry->fileinfo_lock_count == 0) {
return ZEND_HASH_APPLY_REMOVE;
} else {
/* we can't delete this in-memory until it is closed */

View File

@@ -0,0 +1,31 @@
--TEST--
SplFileInfo::openFile() in write mode
--EXTENSIONS--
phar
--INI--
phar.readonly=0
--FILE--
<?php
$phar = new Phar(__DIR__.'/SplFileInfo_openFile_write.phar');
$phar->addFromString('test', 'contents');
var_dump($phar['test']->openFile('w'));
?>
--CLEAN--
<?php
@unlink(__DIR__.'/SplFileInfo_openFile_write.phar');
?>
--EXPECTF--
object(SplFileObject)#%d (%d) {
["pathName":"SplFileInfo":private]=>
string(%d) "phar://%stest"
["fileName":"SplFileInfo":private]=>
string(4) "test"
["openMode":"SplFileObject":private]=>
string(1) "w"
["delimiter":"SplFileObject":private]=>
string(1) ","
["enclosure":"SplFileObject":private]=>
string(1) """
}

View File

@@ -5,18 +5,26 @@ phar
zlib
--FILE--
<?php
$fname = __DIR__.'/tar/files/Structures_Graph-1.0.3.tgz';
$fname = __DIR__.'/tar/files/gh17808.tgz';
copy(__DIR__.'/tar/files/Structures_Graph-1.0.3.tgz', $fname);
$tar = new PharData($fname);
foreach (new RecursiveIteratorIterator($tar) as $file) {
}
var_dump("$file");
var_dump($file);
var_dump(strlen($file->getContent()));
unlink("$file");
unlink($file);
var_dump($file->getATime());
?>
--CLEAN--
<?php
@unlink(__DIR__.'/tar/files/gh17808.tgz');
?>
--EXPECTF--
string(%d) "phar://%spackage.xml"
object(PharFileInfo)#%d (%d) {
["pathName":"SplFileInfo":private]=>
string(%d) "phar://%spackage.xml"
["fileName":"SplFileInfo":private]=>
string(11) "package.xml"
}
int(6747)
Warning: unlink(): phar error: "package.xml" in phar %s, has open file pointers, cannot unlink in %s on line %d
int(33188)

View File

@@ -865,7 +865,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{
}
if (entry->is_deleted) {
if (entry->fp_refcount <= 0) {
if (entry->fp_refcount <= 0 && entry->fileinfo_lock_count == 0) {
return ZEND_HASH_APPLY_REMOVE;
} else {
/* we can't delete this in-memory until it is closed */