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

Merge branch 'PHP-8.1'

* PHP-8.1:
  [ci skip] NEWS
  Fix GH-8952: std streams can not be deliberately closed (#8953)
  intl extension, build fix for icu >= 69.x release. ubrk/ucnv_safeClone had been deprecated in favor of ubrk/ucnv_clone which does not use user provided stacks but remain thread safe.
This commit is contained in:
Arnaud Le Blanc
2022-07-09 23:01:07 +02:00
4 changed files with 148 additions and 8 deletions

View File

@@ -536,14 +536,6 @@ static void cli_register_file_handles(void) /* {{{ */
s_out = php_stream_open_wrapper_ex("php://stdout", "wb", 0, NULL, sc_out);
s_err = php_stream_open_wrapper_ex("php://stderr", "wb", 0, NULL, sc_err);
/* Release stream resources, but don't free the underlying handles. Othewrise,
* extensions which write to stderr or company during mshutdown/gshutdown
* won't have the expected functionality.
*/
if (s_in) s_in->flags |= PHP_STREAM_FLAG_NO_CLOSE;
if (s_out) s_out->flags |= PHP_STREAM_FLAG_NO_CLOSE;
if (s_err) s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE;
if (s_in==NULL || s_out==NULL || s_err==NULL) {
if (s_in) php_stream_close(s_in);
if (s_out) php_stream_close(s_out);
@@ -551,6 +543,12 @@ static void cli_register_file_handles(void) /* {{{ */
return;
}
if (no_close) {
s_in->flags |= PHP_STREAM_FLAG_NO_CLOSE;
s_out->flags |= PHP_STREAM_FLAG_NO_CLOSE;
s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE;
}
s_in_process = s_in;
php_stream_to_zval(s_in, &ic.value);

View File

@@ -0,0 +1,38 @@
--TEST--
std handles can be deliberately closed 001
--SKIPIF--
<?php
if (php_sapi_name() != "cli") {
die("skip CLI only");
}
if (PHP_OS_FAMILY == 'Windows') {
die("skip not for Windows");
}
if (PHP_DEBUG) {
die("skip std streams are not closeable in debug builds");
}
if (getenv('SKIP_REPEAT')) {
die("skip cannot be repeated");
}
?>
--FILE--
<?php
print "STDIN:\n";
fclose(STDIN);
var_dump(@fopen('php://stdin', 'r'));
print "STDERR:\n";
fclose(STDERR);
var_dump(@fopen('php://stderr', 'a'));
print "STDOUT:\n";
fclose(STDOUT);
// not printed if stdout is closed
var_dump(@fopen('php://stdout', 'a'));
?>
--EXPECT--
STDIN:
bool(false)
STDERR:
bool(false)
STDOUT:

View File

@@ -0,0 +1,47 @@
--TEST--
std handles can be deliberately closed 002
--SKIPIF--
<?php
if (php_sapi_name() != "cli") {
die("skip CLI only");
}
if (PHP_OS_FAMILY == 'Windows') {
die("skip not for Windows");
}
if (PHP_DEBUG) {
die("skip std streams are not closeable in debug builds");
}
if (getenv('SKIP_REPEAT')) {
die("skip cannot be repeated");
}
?>
--FILE--
<?php
$stdin = fopen('php://stdin', 'r');
$stdout = fopen('php://stdout', 'r');
$stderr = fopen('php://stderr', 'r');
ob_start(function ($buffer) use ($stdout) {
fwrite($stdout, $buffer);
}, 1);
print "STDIN:\n";
fclose(STDIN);
var_dump(@fopen('php://stdin', 'r'));
print "STDERR:\n";
fclose(STDERR);
var_dump(@fopen('php://stderr', 'a'));
print "STDOUT:\n";
fclose(STDOUT);
var_dump(@fopen('php://stdout', 'a'));
?>
--EXPECT--
STDIN:
bool(false)
STDERR:
bool(false)
STDOUT:
bool(false)

View File

@@ -0,0 +1,57 @@
--TEST--
std handles can be deliberately closed 003
--SKIPIF--
<?php
if (php_sapi_name() != "cli") {
die("skip CLI only");
}
if (PHP_OS_FAMILY == 'Windows') {
die("skip not for Windows");
}
if (PHP_DEBUG) {
die("skip std streams are not closeable in debug builds");
}
if (getenv('SKIP_REPEAT')) {
die("skip cannot be repeated");
}
?>
--FILE--
<?php
$stdoutStream = fopen('php://stdout', 'r');
$stdoutFile = tempnam(sys_get_temp_dir(), 'gh8827');
$stderrFile = tempnam(sys_get_temp_dir(), 'gh8827');
register_shutdown_function(function () use ($stdoutFile, $stderrFile) {
unlink($stdoutFile);
unlink($stderrFile);
});
fclose(STDOUT);
fclose(STDERR);
$stdoutFileStream = fopen($stdoutFile, 'a');
$stderrFileStream = fopen($stderrFile, 'a');
print "Goes to stdoutFile\n";
file_put_contents('php://fd/1', "Also goes to stdoutFile\n");
file_put_contents('php://fd/2', "Goes to stderrFile\n");
ob_start(function ($buffer) use ($stdoutStream) {
fwrite($stdoutStream, $buffer);
}, 1);
print "stdoutFile:\n";
readfile($stdoutFile);
print "stderrFile:\n";
readfile($stderrFile);
?>
--EXPECT--
stdoutFile:
Goes to stdoutFile
Also goes to stdoutFile
stderrFile:
Goes to stderrFile