Skip to content

Commit 58f4b45

Browse files
committed
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2: Fix phpGH-16695: phar:// tar parser and zero-length file header blocks
2 parents 11da498 + 72c0222 commit 58f4b45

File tree

6 files changed

+92
-4
lines changed

6 files changed

+92
-4
lines changed

NEWS

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ PHP NEWS
1919
- PDO:
2020
. Fixed memory leak of `setFetchMode()`. (SakiTakamachi)
2121

22+
- Phar:
23+
. Fixed bug GH-16695 (phar:// tar parser and zero-length file header blocks).
24+
(nielsdos)
25+
2226
- SOAP:
2327
. Fix make check being invoked in ext/soap. (Ma27)
2428

ext/phar/phar.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1774,7 +1774,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char
17741774
return phar_parse_zipfile(fp, fname, fname_len, alias, alias_len, pphar, error);
17751775
}
17761776

1777-
if (got > 512) {
1777+
if (got >= 512) {
17781778
if (phar_is_tar(pos, fname)) {
17791779
php_stream_rewind(fp);
17801780
return phar_parse_tarfile(fp, fname, fname_len, alias, alias_len, pphar, is_data, compression, error);

ext/phar/tar.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,8 @@ int phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alia
247247
entry.is_tar = 1;
248248
entry.is_crc_checked = 1;
249249
entry.phar = myphar;
250-
pos += sizeof(buf);
251250

252-
do {
251+
while (true) {
253252
phar_entry_info *newentry;
254253

255254
pos = php_stream_tell(fp);
@@ -590,6 +589,11 @@ int phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alia
590589
}
591590
}
592591

592+
/* Only read next header if we're not yet at the end */
593+
if (php_stream_tell(fp) == totalsize) {
594+
break;
595+
}
596+
593597
read = php_stream_read(fp, buf, sizeof(buf));
594598

595599
if (read != sizeof(buf)) {
@@ -600,7 +604,7 @@ int phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alia
600604
phar_destroy_phar_data(myphar);
601605
return FAILURE;
602606
}
603-
} while (!php_stream_eof(fp));
607+
}
604608

605609
if (zend_hash_str_exists(&(myphar->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
606610
myphar->is_data = 0;

ext/phar/tests/tar/gh16695_1.phpt

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
GH-16695 (phar:// tar parser and zero-length file header blocks)
3+
--CREDITS--
4+
hakre
5+
--EXTENSIONS--
6+
phar
7+
--INI--
8+
phar.require_hash=0
9+
--FILE--
10+
<?php
11+
12+
$reportTar = __DIR__.'/gh16695_1.tmp';
13+
14+
$length = file_put_contents($reportTar, base64_decode('dGxzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDA3MDAAMDAwMDAwMAAwMDAwMDAwADAwMDAwMDAwMDAwADAwMDAwMDAwMDAwADAwNzcxNgAgNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1c3RhcgAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwADAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='));
15+
var_dump($length);
16+
$buffer = file_get_contents("phar://$reportTar/tls");
17+
var_dump($buffer);
18+
19+
?>
20+
--CLEAN--
21+
<?php
22+
@unlink(__DIR__.'/gh16695_1.tmp');
23+
?>
24+
--EXPECTF--
25+
int(512)
26+
27+
Warning: file_get_contents(%stls): Failed to open stream: phar error: path "tls" is a directory in %s on line %d
28+
bool(false)

ext/phar/tests/tar/gh16695_2.phpt

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
GH-16695 (phar:// tar parser and zero-length file header blocks)
3+
--CREDITS--
4+
hakre
5+
--EXTENSIONS--
6+
phar
7+
--INI--
8+
phar.require_hash=0
9+
--FILE--
10+
<?php
11+
12+
$reportTar = __DIR__.'/gh16695_2.tmp';
13+
14+
$length = file_put_contents($reportTar, base64_decode('bWV0YS5qc29uAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDA2NDQAMDAwMDAwMAAwMDAwMDAwADAwMDAwMDAwMTcyADAwMDAwMDAwMDAwADAxMTAyNgAgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1c3RhcgAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwADAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB7Ik5hbWUiOiJkZWZhdWx0IiwiTWV0YWRhdGEiOnt9LCJFbmRwb2ludHMiOnsiZG9ja2VyIjp7Ikhvc3QiOiJ1bml4Oi8vL3J1bi91c2VyLzEwMDAvZG9ja2VyLnNvY2siLCJTa2lwVExTVmVyaWZ5IjpmYWxzZX19fQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='));
15+
var_dump($length);
16+
$buffer = file_get_contents("phar://$reportTar/meta.json");
17+
var_dump($buffer);
18+
19+
?>
20+
--CLEAN--
21+
<?php
22+
@unlink(__DIR__.'/gh16695_2.tmp');
23+
?>
24+
--EXPECT--
25+
int(1024)
26+
string(122) "{"Name":"default","Metadata":{},"Endpoints":{"docker":{"Host":"unix:///run/user/1000/docker.sock","SkipTLSVerify":false}}}"

ext/phar/tests/tar/gh16695_3.phpt

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
GH-16695 (phar:// tar parser and zero-length file header blocks)
3+
--CREDITS--
4+
hakre
5+
--EXTENSIONS--
6+
phar
7+
--INI--
8+
phar.require_hash=0
9+
--FILE--
10+
<?php
11+
12+
$reportTar = __DIR__.'/gh16695_3.tmp';
13+
14+
$length = file_put_contents($reportTar, base64_decode('dGxzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDA3MDAAMDAwMDAwMAAwMDAwMDAwADAwMDAwMDAwMDAwADAwMDAwMDAwMDAwADAwNzcxMQAgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1c3RhcgAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwADAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='));
15+
var_dump($length);
16+
$buffer = file_get_contents("phar://$reportTar/tls");
17+
var_dump($buffer);
18+
19+
?>
20+
--CLEAN--
21+
<?php
22+
@unlink(__DIR__.'/gh16695_3.tmp');
23+
?>
24+
--EXPECT--
25+
int(512)
26+
string(0) ""

0 commit comments

Comments
 (0)