Skip to content

Commit 66e4d38

Browse files
committed
phar: fix NULL dereference in Phar::webPhar() when SCRIPT_NAME is absent
In the CGI/FastCGI branch of webPhar(), sapi_getenv("SCRIPT_NAME") can return NULL when the upstream server doesn't forward SCRIPT_NAME in the FastCGI params block. The return value was passed directly to strstr() without a NULL check, causing a segfault. Add a NULL guard that jumps to the finish: label, which is already used for the "SCRIPT_NAME doesn't match the phar basename" case. The fix matches the intent of the existing strstr check and requires no new cleanup. Fixes GH-21797
1 parent f7eb5ef commit 66e4d38

2 files changed

Lines changed: 34 additions & 0 deletions

File tree

ext/phar/phar_object.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,9 @@ PHP_METHOD(Phar, webPhar)
649649
char *testit;
650650

651651
testit = sapi_getenv("SCRIPT_NAME", sizeof("SCRIPT_NAME")-1);
652+
if (!testit) {
653+
goto finish;
654+
}
652655
if (!(pt = strstr(testit, basename))) {
653656
efree(testit);
654657
goto finish;

ext/phar/tests/gh21797.phpt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
GH-21797: Phar::webPhar() NULL dereference when SCRIPT_NAME absent from SAPI environment
3+
--EXTENSIONS--
4+
phar
5+
--INI--
6+
phar.readonly=0
7+
phar.require_hash=0
8+
--FILE--
9+
<?php
10+
// The NULL dereference in the CGI/FastCGI branch of webPhar() is not
11+
// reachable from CLI SAPI. This test exercises the CLI code path as a
12+
// regression baseline and verifies the function behaves correctly when
13+
// called outside an HTTP context.
14+
15+
$fname = __DIR__ . '/' . basename(__FILE__, '.php') . '.phar';
16+
17+
$phar = new Phar($fname);
18+
$phar->addFromString('index.php', '<?php echo "ok\n"; ?>');
19+
$phar->setStub('<?php
20+
Phar::webPhar();
21+
__HALT_COMPILER(); ?>');
22+
unset($phar);
23+
24+
// webPhar() with no HTTP context returns silently (no request method set)
25+
include $fname;
26+
echo "no crash\n";
27+
?>
28+
--CLEAN--
29+
<?php @unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.phar'); ?>
30+
--EXPECT--
31+
no crash

0 commit comments

Comments
 (0)