diff --git a/NEWS b/NEWS index 529f07daccb8..cb638e1f064f 100644 --- a/NEWS +++ b/NEWS @@ -232,6 +232,8 @@ PHP NEWS compressed contents after changing compression). (Raphael Paez) . Fixed bug GH-24740 (Oversized tar metadata exhausts the memory limit). (Lazizbek Ergashev) + . Fixed bug GH-25093 (Phar::webPhar() builds the redirect target from the + on-disk path length). (dhrupo) - Phpdbg: . Fix wrong command names. (ndossche, Weilin Du) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index e2f36f1c7b24..cb071f0ca300 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -784,7 +784,7 @@ PHP_METHOD(Phar, webPhar) sapi_header_op(SAPI_HEADER_REPLACE, &ctr); if (not_cgi) { - tmp = strstr(path_info, basename) + fname_len; + tmp = strstr(path_info, basename) + (fname_len - (basename - fname)); sa = *tmp; *tmp = '\0'; } diff --git a/ext/phar/tests/gh25093.phpt b/ext/phar/tests/gh25093.phpt new file mode 100644 index 000000000000..3a573e893f86 --- /dev/null +++ b/ext/phar/tests/gh25093.phpt @@ -0,0 +1,76 @@ +--TEST-- +GH-25093 (Phar::webPhar() builds the redirect target from the on-disk path length) +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +--SKIPIF-- + +--FILE-- +docRoot/sub"); +@unlink("$server->docRoot/sub/app.phar"); +$phar = new Phar("$server->docRoot/sub/app.phar"); +$phar["index.php"] = "setStub(''); +unset($phar); + +function request_redirect(string $uri): void +{ + $client = stream_socket_client("tcp://" . PHP_CLI_SERVER_ADDRESS); + fwrite($client, "GET $uri HTTP/1.1\r\nHost: " . PHP_CLI_SERVER_HOSTNAME . "\r\nConnection: close\r\n\r\n"); + $response = stream_get_contents($client); + fclose($client); + + foreach (explode("\r\n", $response) as $line) { + if ($line === "") { + break; + } + if (str_starts_with($line, "HTTP/") || str_starts_with($line, "Location:")) { + echo $line, "\n"; + } + } +} + +// Requested path longer than the phar's path on disk: the redirect target kept +// part of the requested path. +request_redirect("/sub/app.phar/" . str_repeat("a", strlen($server->docRoot) + 16)); + +// Requested path ending at the phar: the redirect target was measured past the +// end of the request URI. +request_redirect("/sub/app.phar"); +?> +--CLEAN-- + +--EXPECT-- +HTTP/1.1 301 Moved Permanently +Location: /sub/app.phar/index.php +HTTP/1.1 301 Moved Permanently +Location: /sub/app.phar/index.php