Skip to content

Commit 463f13b

Browse files
committed
Merge branch 'master' into issue/20589
2 parents 8a52d73 + 454fe14 commit 463f13b

File tree

17 files changed

+111
-29
lines changed

17 files changed

+111
-29
lines changed

ext/enchant/enchant.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -671,17 +671,18 @@ PHP_FUNCTION(enchant_dict_suggest)
671671
}
672672

673673
PHP_ENCHANT_GET_DICT;
674-
array_init(return_value);
675674

676675
suggs = enchant_dict_suggest(pdict->pdict, word, wordlen, &n_sugg);
677676
if (suggs && n_sugg) {
678-
size_t i;
677+
array_init_size(return_value, n_sugg);
679678

680-
for (i = 0; i < n_sugg; i++) {
679+
for (size_t i = 0; i < n_sugg; i++) {
681680
add_next_index_string(return_value, suggs[i]);
682681
}
683682

684683
enchant_dict_free_string_list(pdict->pdict, suggs);
684+
} else {
685+
RETURN_EMPTY_ARRAY();
685686
}
686687
}
687688
/* }}} */

ext/phar/phar.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ ZEND_ATTRIBUTE_NONNULL void phar_entry_remove(phar_entry_data *idata, char **err
420420

421421
phar = idata->phar;
422422

423-
if (idata->internal_file->fp_refcount < 2) {
423+
if (idata->internal_file->fp_refcount < 2 && idata->internal_file->fileinfo_lock_count == 0) {
424424
if (idata->fp && idata->fp != idata->phar->fp && idata->fp != idata->phar->ufp && idata->fp != idata->internal_file->fp) {
425425
php_stream_close(idata->fp);
426426
}
@@ -1571,7 +1571,7 @@ static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_l
15711571
const zend_long readsize = sizeof(buffer) - sizeof(token);
15721572
const zend_long tokenlen = sizeof(token) - 1;
15731573
zend_long halt_offset;
1574-
size_t got;
1574+
ssize_t got;
15751575
uint32_t compression = PHAR_FILE_COMPRESSED_NONE;
15761576

15771577
if (error) {
@@ -1589,7 +1589,7 @@ static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_l
15891589
/* Maybe it's better to compile the file instead of just searching, */
15901590
/* but we only want the offset. So we want a .re scanner to find it. */
15911591
while(!php_stream_eof(fp)) {
1592-
if ((got = php_stream_read(fp, buffer+tokenlen, readsize)) < (size_t) tokenlen) {
1592+
if ((got = php_stream_read(fp, buffer+tokenlen, readsize)) < tokenlen) {
15931593
MAPPHAR_ALLOC_FAIL("internal corruption of phar \"%s\" (truncated entry)")
15941594
}
15951595

ext/phar/phar_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ typedef struct _phar_entry_info {
216216
php_stream *cfp;
217217
enum phar_fp_type fp_type;
218218
int fp_refcount;
219+
unsigned int fileinfo_lock_count;
219220
char *tmp;
220221
phar_archive_data *phar;
221222
char *link; /* symbolic link to another file */

ext/phar/phar_object.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4441,7 +4441,7 @@ PHP_METHOD(PharFileInfo, __construct)
44414441

44424442
entry_obj->entry = entry_info;
44434443
if (!entry_info->is_persistent && !entry_info->is_temp_dir) {
4444-
++entry_info->fp_refcount;
4444+
++entry_info->fileinfo_lock_count;
44454445
/* The phar data must exist to keep the alias locked. */
44464446
ZEND_ASSERT(!phar_data->is_persistent);
44474447
++phar_data->refcount;
@@ -4486,7 +4486,7 @@ PHP_METHOD(PharFileInfo, __destruct)
44864486
efree(entry);
44874487
entry_obj->entry = NULL;
44884488
} else if (!entry->is_persistent) {
4489-
--entry->fp_refcount;
4489+
--entry->fileinfo_lock_count;
44904490
/* The entry itself still lives in the manifest,
44914491
* which will either be freed here if the file info was the last reference; or freed later. */
44924492
entry_obj->entry = NULL;

ext/phar/tar.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,7 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /*
726726
}
727727

728728
if (entry->is_deleted) {
729-
if (entry->fp_refcount <= 0) {
729+
if (entry->fp_refcount <= 0 && entry->fileinfo_lock_count == 0) {
730730
return ZEND_HASH_APPLY_REMOVE;
731731
} else {
732732
/* we can't delete this in-memory until it is closed */
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
SplFileInfo::openFile() in write mode
3+
--EXTENSIONS--
4+
phar
5+
--INI--
6+
phar.readonly=0
7+
--FILE--
8+
<?php
9+
10+
$phar = new Phar(__DIR__.'/SplFileInfo_openFile_write.phar');
11+
$phar->addFromString('test', 'contents');
12+
var_dump($phar['test']->openFile('w'));
13+
14+
?>
15+
--CLEAN--
16+
<?php
17+
@unlink(__DIR__.'/SplFileInfo_openFile_write.phar');
18+
?>
19+
--EXPECTF--
20+
object(SplFileObject)#%d (%d) {
21+
["pathName":"SplFileInfo":private]=>
22+
string(%d) "phar://%stest"
23+
["fileName":"SplFileInfo":private]=>
24+
string(4) "test"
25+
["openMode":"SplFileObject":private]=>
26+
string(1) "w"
27+
["delimiter":"SplFileObject":private]=>
28+
string(1) ","
29+
["enclosure":"SplFileObject":private]=>
30+
string(1) """
31+
}

ext/phar/tests/gh17808.phpt

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,26 @@ phar
55
zlib
66
--FILE--
77
<?php
8-
$fname = __DIR__.'/tar/files/Structures_Graph-1.0.3.tgz';
8+
$fname = __DIR__.'/tar/files/gh17808.tgz';
9+
copy(__DIR__.'/tar/files/Structures_Graph-1.0.3.tgz', $fname);
910
$tar = new PharData($fname);
1011
foreach (new RecursiveIteratorIterator($tar) as $file) {
1112
}
12-
var_dump("$file");
13+
var_dump($file);
1314
var_dump(strlen($file->getContent()));
14-
unlink("$file");
15+
unlink($file);
1516
var_dump($file->getATime());
1617
?>
18+
--CLEAN--
19+
<?php
20+
@unlink(__DIR__.'/tar/files/gh17808.tgz');
21+
?>
1722
--EXPECTF--
18-
string(%d) "phar://%spackage.xml"
23+
object(PharFileInfo)#%d (%d) {
24+
["pathName":"SplFileInfo":private]=>
25+
string(%d) "phar://%spackage.xml"
26+
["fileName":"SplFileInfo":private]=>
27+
string(11) "package.xml"
28+
}
1929
int(6747)
20-
21-
Warning: unlink(): phar error: "package.xml" in phar %s, has open file pointers, cannot unlink in %s on line %d
2230
int(33188)

ext/phar/tests/gh20732.phpt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
GH-20732 (Phar::LoadPhar undefined behavior when loading directory)
3+
--EXTENSIONS--
4+
phar
5+
--FILE--
6+
<?php
7+
try {
8+
@Phar::LoadPhar('.');
9+
} catch (PharException $e) {
10+
echo $e->getMessage(), "\n";
11+
}
12+
?>
13+
--EXPECTF--
14+
%r(internal corruption of phar "%s" \(truncated entry\)|unable to open phar for reading ".")%r

ext/phar/zip.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{
851851
}
852852

853853
if (entry->is_deleted) {
854-
if (entry->fp_refcount <= 0) {
854+
if (entry->fp_refcount <= 0 && entry->fileinfo_lock_count == 0) {
855855
return ZEND_HASH_APPLY_REMOVE;
856856
} else {
857857
/* we can't delete this in-memory until it is closed */

ext/standard/file.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -663,11 +663,10 @@ PHP_FUNCTION(file)
663663
p = e;
664664
goto parse_eol;
665665
}
666-
}
667666

668-
if (target_buf) {
669-
zend_string_free(target_buf);
667+
zend_string_efree(target_buf);
670668
}
669+
671670
php_stream_close(stream);
672671
}
673672
/* }}} */
@@ -1555,7 +1554,6 @@ PHPAPI PHP_FUNCTION(fread)
15551554

15561555
str = php_stream_read_to_str(stream, len);
15571556
if (!str) {
1558-
zval_ptr_dtor_str(return_value);
15591557
RETURN_FALSE;
15601558
}
15611559

0 commit comments

Comments
 (0)