mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Merge branch 'PHP-8.5'
* PHP-8.5: Revert "Deprecate returning non-string values from a user output handler (#18932)" (#20455)
This commit is contained in:
@@ -956,7 +956,6 @@ static inline php_output_handler_status_t php_output_handler_op(php_output_handl
|
||||
if (handler->flags & PHP_OUTPUT_HANDLER_USER) {
|
||||
zval ob_args[2];
|
||||
zval retval;
|
||||
ZVAL_UNDEF(&retval);
|
||||
|
||||
/* ob_data */
|
||||
ZVAL_STRINGL(&ob_args[0], handler->buffer.data, handler->buffer.used);
|
||||
@@ -969,17 +968,10 @@ static inline php_output_handler_status_t php_output_handler_op(php_output_handl
|
||||
handler->func.user->fci.retval = &retval;
|
||||
|
||||
if (SUCCESS == zend_call_function(&handler->func.user->fci, &handler->func.user->fcc) && Z_TYPE(retval) != IS_UNDEF) {
|
||||
if (Z_TYPE(retval) != IS_STRING || handler->flags & PHP_OUTPUT_HANDLER_PRODUCED_OUTPUT) {
|
||||
if (handler->flags & PHP_OUTPUT_HANDLER_PRODUCED_OUTPUT) {
|
||||
// Make sure that we don't get lost in the current output buffer
|
||||
// by disabling it
|
||||
handler->flags |= PHP_OUTPUT_HANDLER_DISABLED;
|
||||
// Make sure we keep a reference to the handler name in
|
||||
// case
|
||||
// * The handler produced output *and* returned a non-string
|
||||
// * The first deprecation message causes the handler to
|
||||
// be removed
|
||||
zend_string *handler_name = handler->name;
|
||||
zend_string_addref(handler_name);
|
||||
if (handler->flags & PHP_OUTPUT_HANDLER_PRODUCED_OUTPUT) {
|
||||
// The handler might not always produce output
|
||||
handler->flags &= ~PHP_OUTPUT_HANDLER_PRODUCED_OUTPUT;
|
||||
@@ -987,18 +979,9 @@ static inline php_output_handler_status_t php_output_handler_op(php_output_handl
|
||||
NULL,
|
||||
E_DEPRECATED,
|
||||
"Producing output from user output handler %s is deprecated",
|
||||
ZSTR_VAL(handler_name)
|
||||
ZSTR_VAL(handler->name)
|
||||
);
|
||||
}
|
||||
if (Z_TYPE(retval) != IS_STRING) {
|
||||
php_error_docref(
|
||||
NULL,
|
||||
E_DEPRECATED,
|
||||
"Returning a non-string result from user output handler %s is deprecated",
|
||||
ZSTR_VAL(handler_name)
|
||||
);
|
||||
}
|
||||
zend_string_release(handler_name);
|
||||
|
||||
// Check if the handler is still in the list of handlers to
|
||||
// determine if the PHP_OUTPUT_HANDLER_DISABLED flag can
|
||||
|
||||
@@ -35,24 +35,19 @@ foreach ($callbacks as $callback) {
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
--EXPECT--
|
||||
--> Use callback 'return_empty_string':
|
||||
|
||||
|
||||
--> Use callback 'return_false':
|
||||
|
||||
Deprecated: ob_end_flush(): Returning a non-string result from user output handler return_false is deprecated in %s on line %d
|
||||
My output.
|
||||
|
||||
--> Use callback 'return_null':
|
||||
|
||||
Deprecated: ob_end_flush(): Returning a non-string result from user output handler return_null is deprecated in %s on line %d
|
||||
|
||||
|
||||
--> Use callback 'return_string':
|
||||
I stole your output.
|
||||
|
||||
--> Use callback 'return_zero':
|
||||
|
||||
Deprecated: ob_end_flush(): Returning a non-string result from user output handler return_zero is deprecated in %s on line %d
|
||||
0
|
||||
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
--TEST--
|
||||
ob_start(): Check behaviour with deprecation converted to exception [bad return]
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class NotStringable {
|
||||
public function __construct(public string $val) {}
|
||||
}
|
||||
class IsStringable {
|
||||
public function __construct(public string $val) {}
|
||||
public function __toString() {
|
||||
return __CLASS__ . ": " . $this->val;
|
||||
}
|
||||
}
|
||||
|
||||
$log = [];
|
||||
|
||||
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) {
|
||||
throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
|
||||
});
|
||||
|
||||
function return_null($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return null;
|
||||
}
|
||||
|
||||
function return_false($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return false;
|
||||
}
|
||||
|
||||
function return_true($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return true;
|
||||
}
|
||||
|
||||
function return_zero($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return 0;
|
||||
}
|
||||
|
||||
function return_non_stringable($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return new NotStringable($string);
|
||||
}
|
||||
|
||||
function return_stringable($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return new IsStringable($string);
|
||||
}
|
||||
|
||||
$cases = [
|
||||
'return_null',
|
||||
'return_false',
|
||||
'return_true',
|
||||
'return_zero',
|
||||
'return_non_stringable',
|
||||
'return_stringable',
|
||||
];
|
||||
foreach ($cases as $case) {
|
||||
$log = [];
|
||||
echo "\n\nTesting: $case\n";
|
||||
ob_start($case);
|
||||
echo "Inside of $case\n";
|
||||
try {
|
||||
ob_end_flush();
|
||||
} catch (\ErrorException $e) {
|
||||
echo $e . "\n";
|
||||
}
|
||||
echo "\nEnd of $case, log was:\n";
|
||||
echo implode("\n", $log);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Testing: return_null
|
||||
ErrorException: ob_end_flush(): Returning a non-string result from user output handler return_null is deprecated in %s:%d
|
||||
Stack trace:
|
||||
#0 [internal function]: {closure:%s:%d}(8192, 'ob_end_flush():...', %s, %d)
|
||||
#1 %s(%d): ob_end_flush()
|
||||
#2 {main}
|
||||
|
||||
End of return_null, log was:
|
||||
return_null: <<<Inside of return_null
|
||||
>>>
|
||||
|
||||
Testing: return_false
|
||||
Inside of return_false
|
||||
ErrorException: ob_end_flush(): Returning a non-string result from user output handler return_false is deprecated in %s:%d
|
||||
Stack trace:
|
||||
#0 [internal function]: {closure:%s:%d}(8192, 'ob_end_flush():...', %s, %d)
|
||||
#1 %s(%d): ob_end_flush()
|
||||
#2 {main}
|
||||
|
||||
End of return_false, log was:
|
||||
return_false: <<<Inside of return_false
|
||||
>>>
|
||||
|
||||
Testing: return_true
|
||||
ErrorException: ob_end_flush(): Returning a non-string result from user output handler return_true is deprecated in %s:%d
|
||||
Stack trace:
|
||||
#0 [internal function]: {closure:%s:%d}(8192, 'ob_end_flush():...', %s, %d)
|
||||
#1 %s(%d): ob_end_flush()
|
||||
#2 {main}
|
||||
|
||||
End of return_true, log was:
|
||||
return_true: <<<Inside of return_true
|
||||
>>>
|
||||
|
||||
Testing: return_zero
|
||||
0ErrorException: ob_end_flush(): Returning a non-string result from user output handler return_zero is deprecated in %s:%d
|
||||
Stack trace:
|
||||
#0 [internal function]: {closure:%s:%d}(8192, 'ob_end_flush():...', %s, %d)
|
||||
#1 %s(%d): ob_end_flush()
|
||||
#2 {main}
|
||||
|
||||
End of return_zero, log was:
|
||||
return_zero: <<<Inside of return_zero
|
||||
>>>
|
||||
|
||||
Testing: return_non_stringable
|
||||
ErrorException: ob_end_flush(): Returning a non-string result from user output handler return_non_stringable is deprecated in %s:%d
|
||||
Stack trace:
|
||||
#0 [internal function]: {closure:%s:%d}(8192, 'ob_end_flush():...', %s, 69)
|
||||
#1 %s(%d): ob_end_flush()
|
||||
#2 {main}
|
||||
|
||||
End of return_non_stringable, log was:
|
||||
return_non_stringable: <<<Inside of return_non_stringable
|
||||
>>>
|
||||
|
||||
Testing: return_stringable
|
||||
ErrorException: ob_end_flush(): Returning a non-string result from user output handler return_stringable is deprecated in %s:%d
|
||||
Stack trace:
|
||||
#0 [internal function]: {closure:%s:%d}(8192, 'ob_end_flush():...', %s, 69)
|
||||
#1 %s(%d): ob_end_flush()
|
||||
#2 {main}
|
||||
|
||||
End of return_stringable, log was:
|
||||
return_stringable: <<<Inside of return_stringable
|
||||
>>>
|
||||
@@ -1,143 +0,0 @@
|
||||
--TEST--
|
||||
ob_start(): Check behaviour with nested deprecation converted to exception [bad return]
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class NotStringable {
|
||||
public function __construct(public string $val) {}
|
||||
}
|
||||
class IsStringable {
|
||||
public function __construct(public string $val) {}
|
||||
public function __toString() {
|
||||
return __CLASS__ . ": " . $this->val;
|
||||
}
|
||||
}
|
||||
|
||||
$log = [];
|
||||
|
||||
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) {
|
||||
throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
|
||||
});
|
||||
|
||||
function return_null($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return null;
|
||||
}
|
||||
|
||||
function return_false($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return false;
|
||||
}
|
||||
|
||||
function return_true($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return true;
|
||||
}
|
||||
|
||||
function return_zero($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return 0;
|
||||
}
|
||||
|
||||
function return_non_stringable($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return new NotStringable($string);
|
||||
}
|
||||
|
||||
function return_stringable($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return new IsStringable($string);
|
||||
}
|
||||
|
||||
ob_start('return_null');
|
||||
ob_start('return_false');
|
||||
ob_start('return_true');
|
||||
ob_start('return_zero');
|
||||
ob_start('return_non_stringable');
|
||||
ob_start('return_stringable');
|
||||
|
||||
echo "In all of them\n\n";
|
||||
try {
|
||||
ob_end_flush();
|
||||
} catch (\ErrorException $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
echo "Ended return_stringable handler\n\n";
|
||||
|
||||
try {
|
||||
ob_end_flush();
|
||||
} catch (\ErrorException $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
echo "Ended return_non_stringable handler\n\n";
|
||||
|
||||
try {
|
||||
ob_end_flush();
|
||||
} catch (\ErrorException $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
echo "Ended return_zero handler\n\n";
|
||||
|
||||
try {
|
||||
ob_end_flush();
|
||||
} catch (\ErrorException $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
echo "Ended return_true handler\n\n";
|
||||
|
||||
try {
|
||||
ob_end_flush();
|
||||
} catch (\ErrorException $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
echo "Ended return_false handler\n\n";
|
||||
|
||||
try {
|
||||
ob_end_flush();
|
||||
} catch (\ErrorException $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
echo "Ended return_null handler\n\n";
|
||||
|
||||
echo "All handlers are over\n\n";
|
||||
echo implode("\n", $log);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
ob_end_flush(): Returning a non-string result from user output handler return_null is deprecated
|
||||
Ended return_null handler
|
||||
|
||||
All handlers are over
|
||||
|
||||
return_stringable: <<<In all of them
|
||||
|
||||
>>>
|
||||
return_non_stringable: <<<ob_end_flush(): Returning a non-string result from user output handler return_stringable is deprecated
|
||||
Ended return_stringable handler
|
||||
|
||||
>>>
|
||||
return_zero: <<<ob_end_flush(): Returning a non-string result from user output handler return_non_stringable is deprecated
|
||||
Ended return_non_stringable handler
|
||||
|
||||
>>>
|
||||
return_true: <<<0ob_end_flush(): Returning a non-string result from user output handler return_zero is deprecated
|
||||
Ended return_zero handler
|
||||
|
||||
>>>
|
||||
return_false: <<<ob_end_flush(): Returning a non-string result from user output handler return_true is deprecated
|
||||
Ended return_true handler
|
||||
|
||||
>>>
|
||||
return_null: <<<ob_end_flush(): Returning a non-string result from user output handler return_true is deprecated
|
||||
Ended return_true handler
|
||||
|
||||
ob_end_flush(): Returning a non-string result from user output handler return_false is deprecated
|
||||
Ended return_false handler
|
||||
|
||||
>>>
|
||||
@@ -1,23 +0,0 @@
|
||||
--TEST--
|
||||
ob_start(): Check behaviour with deprecation when OOM triggers handler removal (handler returns false)
|
||||
--INI--
|
||||
memory_limit=2M
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
ob_start(function() {
|
||||
// We are out of memory, now trigger a deprecation
|
||||
return false;
|
||||
});
|
||||
|
||||
$a = [];
|
||||
// trigger OOM in a resize operation
|
||||
while (1) {
|
||||
$a[] = 1;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: main(): Returning a non-string result from user output handler {closure:%s:%d} is deprecated in %s on line %d
|
||||
|
||||
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
|
||||
@@ -1,30 +0,0 @@
|
||||
--TEST--
|
||||
ob_start(): Check behaviour with deprecation when OOM triggers handler removal (handler returns stringable object)
|
||||
--INI--
|
||||
memory_limit=2M
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class IsStringable {
|
||||
public function __construct(public string $val) {}
|
||||
public function __toString() {
|
||||
return __CLASS__ . ": " . $this->val;
|
||||
}
|
||||
}
|
||||
|
||||
ob_start(function() {
|
||||
// We are out of memory, now trigger a deprecation
|
||||
return new IsStringable("");
|
||||
});
|
||||
|
||||
$a = [];
|
||||
// trigger OOM in a resize operation
|
||||
while (1) {
|
||||
$a[] = 1;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: main(): Returning a non-string result from user output handler {closure:%s:%d} is deprecated in %s on line %d
|
||||
|
||||
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
|
||||
@@ -1,32 +0,0 @@
|
||||
--TEST--
|
||||
ob_start(): Check behaviour with deprecation when OOM triggers handler removal (handler returns non-stringable object)
|
||||
--INI--
|
||||
memory_limit=2M
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class NotStringable {
|
||||
public function __construct(public string $val) {}
|
||||
}
|
||||
|
||||
ob_start(function() {
|
||||
// We are out of memory, now trigger a deprecation
|
||||
return new NotStringable("");
|
||||
});
|
||||
|
||||
$a = [];
|
||||
// trigger OOM in a resize operation
|
||||
while (1) {
|
||||
$a[] = 1;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: main(): Returning a non-string result from user output handler {closure:%s:%d} is deprecated in %s on line %d
|
||||
|
||||
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
|
||||
|
||||
Fatal error: Uncaught Error: Object of class NotStringable could not be converted to string in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %s on line %d
|
||||
@@ -1,23 +0,0 @@
|
||||
--TEST--
|
||||
ob_start(): Check behaviour with deprecation when OOM triggers handler removal (handler returns true)
|
||||
--INI--
|
||||
memory_limit=2M
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
ob_start(function() {
|
||||
// We are out of memory, now trigger a deprecation
|
||||
return true;
|
||||
});
|
||||
|
||||
$a = [];
|
||||
// trigger OOM in a resize operation
|
||||
while (1) {
|
||||
$a[] = 1;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: main(): Returning a non-string result from user output handler {closure:%s:%d} is deprecated in %s on line %d
|
||||
|
||||
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
|
||||
@@ -1,23 +0,0 @@
|
||||
--TEST--
|
||||
ob_start(): Check behaviour with deprecation when OOM triggers handler removal (handler returns zero)
|
||||
--INI--
|
||||
memory_limit=2M
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
ob_start(function() {
|
||||
// We are out of memory, now trigger a deprecation
|
||||
return 0;
|
||||
});
|
||||
|
||||
$a = [];
|
||||
// trigger OOM in a resize operation
|
||||
while (1) {
|
||||
$a[] = 1;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: main(): Returning a non-string result from user output handler {closure:%s:%d} is deprecated in %s on line %d
|
||||
|
||||
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
|
||||
@@ -1,106 +0,0 @@
|
||||
--TEST--
|
||||
ob_start(): Check behaviour with multiple nested handlers with bad return values
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$log = [];
|
||||
|
||||
function return_given_string($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return $string;
|
||||
}
|
||||
|
||||
function return_empty_string($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return "";
|
||||
}
|
||||
|
||||
function return_false($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return false;
|
||||
}
|
||||
|
||||
function return_true($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return true;
|
||||
}
|
||||
|
||||
function return_null($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return null;
|
||||
}
|
||||
|
||||
function return_string($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return "I stole your output.";
|
||||
}
|
||||
|
||||
function return_zero($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
return 0;
|
||||
}
|
||||
|
||||
ob_start('return_given_string');
|
||||
ob_start('return_empty_string');
|
||||
ob_start('return_false');
|
||||
ob_start('return_true');
|
||||
ob_start('return_null');
|
||||
ob_start('return_string');
|
||||
ob_start('return_zero');
|
||||
|
||||
echo "Testing...";
|
||||
|
||||
ob_end_flush();
|
||||
ob_end_flush();
|
||||
ob_end_flush();
|
||||
ob_end_flush();
|
||||
ob_end_flush();
|
||||
ob_end_flush();
|
||||
ob_end_flush();
|
||||
|
||||
echo "\n\nLog:\n";
|
||||
echo implode("\n", $log);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: ob_end_flush(): Producing output from user output handler return_given_string is deprecated in %s on line %d3
|
||||
|
||||
Deprecated: ob_end_flush(): Producing output from user output handler return_empty_string is deprecated in %s on line %d2
|
||||
|
||||
|
||||
Log:
|
||||
return_zero: <<<Testing...>>>
|
||||
return_string: <<<
|
||||
Deprecated: ob_end_flush(): Returning a non-string result from user output handler return_zero is deprecated in %s on line %d
|
||||
0>>>
|
||||
return_null: <<<
|
||||
Deprecated: ob_end_flush(): Producing output from user output handler return_string is deprecated in %s on line %d
|
||||
I stole your output.>>>
|
||||
return_true: <<<
|
||||
Deprecated: ob_end_flush(): Producing output from user output handler return_null is deprecated in %s on line %d
|
||||
|
||||
Deprecated: ob_end_flush(): Returning a non-string result from user output handler return_null is deprecated in %s on line %d
|
||||
>>>
|
||||
return_false: <<<
|
||||
Deprecated: ob_end_flush(): Producing output from user output handler return_true is deprecated in %s on line %d
|
||||
|
||||
Deprecated: ob_end_flush(): Returning a non-string result from user output handler return_true is deprecated in %s on line %d
|
||||
>>>
|
||||
return_empty_string: <<<
|
||||
Deprecated: ob_end_flush(): Producing output from user output handler return_false is deprecated in %s on line %d
|
||||
|
||||
Deprecated: ob_end_flush(): Returning a non-string result from user output handler return_false is deprecated in %s on line %d
|
||||
|
||||
Deprecated: ob_end_flush(): Producing output from user output handler return_true is deprecated in %s on line %d
|
||||
|
||||
Deprecated: ob_end_flush(): Returning a non-string result from user output handler return_true is deprecated in %s on line %d
|
||||
>>>
|
||||
return_given_string: <<<
|
||||
Deprecated: ob_end_flush(): Producing output from user output handler return_empty_string is deprecated in %s on line %d2
|
||||
>>>
|
||||
@@ -1,153 +0,0 @@
|
||||
--TEST--
|
||||
ob_start(): Check behaviour with deprecation converted to exception [bad return + produce output]
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class NotStringable {
|
||||
public function __construct(public string $val) {}
|
||||
}
|
||||
class IsStringable {
|
||||
public function __construct(public string $val) {}
|
||||
public function __toString() {
|
||||
return __CLASS__ . ": " . $this->val;
|
||||
}
|
||||
}
|
||||
|
||||
$log = [];
|
||||
|
||||
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) {
|
||||
throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
|
||||
});
|
||||
|
||||
function return_null($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return null;
|
||||
}
|
||||
|
||||
function return_false($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return false;
|
||||
}
|
||||
|
||||
function return_true($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return true;
|
||||
}
|
||||
|
||||
function return_zero($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return 0;
|
||||
}
|
||||
|
||||
function return_non_stringable($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return new NotStringable($string);
|
||||
}
|
||||
|
||||
function return_stringable($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return new IsStringable($string);
|
||||
}
|
||||
|
||||
$cases = [
|
||||
'return_null',
|
||||
'return_false',
|
||||
'return_true',
|
||||
'return_zero',
|
||||
'return_non_stringable',
|
||||
'return_stringable',
|
||||
];
|
||||
foreach ($cases as $case) {
|
||||
$log = [];
|
||||
echo "\n\nTesting: $case\n";
|
||||
ob_start($case);
|
||||
echo "Inside of $case\n";
|
||||
try {
|
||||
ob_end_flush();
|
||||
} catch (\ErrorException $e) {
|
||||
echo $e . "\n";
|
||||
}
|
||||
echo "\nEnd of $case, log was:\n";
|
||||
echo implode("\n", $log);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Testing: return_null
|
||||
ErrorException: ob_end_flush(): Producing output from user output handler return_null is deprecated in %s:%d
|
||||
Stack trace:
|
||||
#0 [internal function]: {closure:%s:%d}(8192, 'ob_end_flush():...', %s, %d)
|
||||
#1 %s(%d): ob_end_flush()
|
||||
#2 {main}
|
||||
|
||||
End of return_null, log was:
|
||||
return_null: <<<Inside of return_null
|
||||
>>>
|
||||
|
||||
Testing: return_false
|
||||
Inside of return_false
|
||||
return_falseErrorException: ob_end_flush(): Producing output from user output handler return_false is deprecated in %s:%d
|
||||
Stack trace:
|
||||
#0 [internal function]: {closure:%s:%d}(8192, 'ob_end_flush():...', %s, %d)
|
||||
#1 %s(%d): ob_end_flush()
|
||||
#2 {main}
|
||||
|
||||
End of return_false, log was:
|
||||
return_false: <<<Inside of return_false
|
||||
>>>
|
||||
|
||||
Testing: return_true
|
||||
ErrorException: ob_end_flush(): Producing output from user output handler return_true is deprecated in %s:%d
|
||||
Stack trace:
|
||||
#0 [internal function]: {closure:%s:%d}(8192, 'ob_end_flush():...', %s, %d)
|
||||
#1 %s(%d): ob_end_flush()
|
||||
#2 {main}
|
||||
|
||||
End of return_true, log was:
|
||||
return_true: <<<Inside of return_true
|
||||
>>>
|
||||
|
||||
Testing: return_zero
|
||||
0ErrorException: ob_end_flush(): Producing output from user output handler return_zero is deprecated in %s:%d
|
||||
Stack trace:
|
||||
#0 [internal function]: {closure:%s:%d}(8192, 'ob_end_flush():...', %s, %d)
|
||||
#1 %s(%d): ob_end_flush()
|
||||
#2 {main}
|
||||
|
||||
End of return_zero, log was:
|
||||
return_zero: <<<Inside of return_zero
|
||||
>>>
|
||||
|
||||
Testing: return_non_stringable
|
||||
ErrorException: ob_end_flush(): Producing output from user output handler return_non_stringable is deprecated in %s:%d
|
||||
Stack trace:
|
||||
#0 [internal function]: {closure:%s:%d}(8192, 'ob_end_flush():...', %s, %d)
|
||||
#1 %s(%d): ob_end_flush()
|
||||
#2 {main}
|
||||
|
||||
End of return_non_stringable, log was:
|
||||
return_non_stringable: <<<Inside of return_non_stringable
|
||||
>>>
|
||||
|
||||
Testing: return_stringable
|
||||
ErrorException: ob_end_flush(): Producing output from user output handler return_stringable is deprecated in %s:%d
|
||||
Stack trace:
|
||||
#0 [internal function]: {closure:%s:%d}(8192, 'ob_end_flush():...', %s, %d)
|
||||
#1 %s(%d): ob_end_flush()
|
||||
#2 {main}
|
||||
|
||||
End of return_stringable, log was:
|
||||
return_stringable: <<<Inside of return_stringable
|
||||
>>>
|
||||
@@ -1,149 +0,0 @@
|
||||
--TEST--
|
||||
ob_start(): Check behaviour with nested deprecation converted to exception [bad return + produce output]
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class NotStringable {
|
||||
public function __construct(public string $val) {}
|
||||
}
|
||||
class IsStringable {
|
||||
public function __construct(public string $val) {}
|
||||
public function __toString() {
|
||||
return __CLASS__ . ": " . $this->val;
|
||||
}
|
||||
}
|
||||
|
||||
$log = [];
|
||||
|
||||
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) {
|
||||
throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
|
||||
});
|
||||
|
||||
function return_null($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return null;
|
||||
}
|
||||
|
||||
function return_false($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return false;
|
||||
}
|
||||
|
||||
function return_true($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return true;
|
||||
}
|
||||
|
||||
function return_zero($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return 0;
|
||||
}
|
||||
|
||||
function return_non_stringable($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return new NotStringable($string);
|
||||
}
|
||||
|
||||
function return_stringable($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return new IsStringable($string);
|
||||
}
|
||||
|
||||
ob_start('return_null');
|
||||
ob_start('return_false');
|
||||
ob_start('return_true');
|
||||
ob_start('return_zero');
|
||||
ob_start('return_non_stringable');
|
||||
ob_start('return_stringable');
|
||||
|
||||
echo "In all of them\n\n";
|
||||
try {
|
||||
ob_end_flush();
|
||||
} catch (\ErrorException $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
echo "Ended return_stringable handler\n\n";
|
||||
|
||||
try {
|
||||
ob_end_flush();
|
||||
} catch (\ErrorException $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
echo "Ended return_non_stringable handler\n\n";
|
||||
|
||||
try {
|
||||
ob_end_flush();
|
||||
} catch (\ErrorException $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
echo "Ended return_zero handler\n\n";
|
||||
|
||||
try {
|
||||
ob_end_flush();
|
||||
} catch (\ErrorException $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
echo "Ended return_true handler\n\n";
|
||||
|
||||
try {
|
||||
ob_end_flush();
|
||||
} catch (\ErrorException $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
echo "Ended return_false handler\n\n";
|
||||
|
||||
try {
|
||||
ob_end_flush();
|
||||
} catch (\ErrorException $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
echo "Ended return_null handler\n\n";
|
||||
|
||||
echo "All handlers are over\n\n";
|
||||
echo implode("\n", $log);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
ob_end_flush(): Producing output from user output handler return_null is deprecated
|
||||
Ended return_null handler
|
||||
|
||||
All handlers are over
|
||||
|
||||
return_stringable: <<<In all of them
|
||||
|
||||
>>>
|
||||
return_non_stringable: <<<ob_end_flush(): Producing output from user output handler return_stringable is deprecated
|
||||
Ended return_stringable handler
|
||||
|
||||
>>>
|
||||
return_zero: <<<ob_end_flush(): Producing output from user output handler return_non_stringable is deprecated
|
||||
Ended return_non_stringable handler
|
||||
|
||||
>>>
|
||||
return_true: <<<0ob_end_flush(): Producing output from user output handler return_zero is deprecated
|
||||
Ended return_zero handler
|
||||
|
||||
>>>
|
||||
return_false: <<<ob_end_flush(): Producing output from user output handler return_true is deprecated
|
||||
Ended return_true handler
|
||||
|
||||
>>>
|
||||
return_null: <<<ob_end_flush(): Producing output from user output handler return_true is deprecated
|
||||
Ended return_true handler
|
||||
|
||||
return_falseob_end_flush(): Producing output from user output handler return_false is deprecated
|
||||
Ended return_false handler
|
||||
|
||||
>>>
|
||||
@@ -1,26 +0,0 @@
|
||||
--TEST--
|
||||
ob_start(): Check behaviour with deprecation when OOM triggers handler removal (handler returns false + produces output)
|
||||
--INI--
|
||||
memory_limit=2M
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
ob_start(function() {
|
||||
// We are out of memory, now trigger a deprecation
|
||||
echo "IN HANDLER\n";
|
||||
return false;
|
||||
});
|
||||
|
||||
$a = [];
|
||||
// trigger OOM in a resize operation
|
||||
while (1) {
|
||||
$a[] = 1;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: main(): Producing output from user output handler {closure:%s:%d} is deprecated in %s on line %d
|
||||
|
||||
Deprecated: main(): Returning a non-string result from user output handler {closure:%s:%d} is deprecated in %s on line %d
|
||||
|
||||
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
|
||||
@@ -1,33 +0,0 @@
|
||||
--TEST--
|
||||
ob_start(): Check behaviour with deprecation when OOM triggers handler removal (handler returns stringable object + produces output)
|
||||
--INI--
|
||||
memory_limit=2M
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class IsStringable {
|
||||
public function __construct(public string $val) {}
|
||||
public function __toString() {
|
||||
return __CLASS__ . ": " . $this->val;
|
||||
}
|
||||
}
|
||||
|
||||
ob_start(function() {
|
||||
// We are out of memory, now trigger a deprecation
|
||||
echo "IN HANDLER\n";
|
||||
return new IsStringable("");
|
||||
});
|
||||
|
||||
$a = [];
|
||||
// trigger OOM in a resize operation
|
||||
while (1) {
|
||||
$a[] = 1;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: main(): Producing output from user output handler {closure:%s:%d} is deprecated in %s on line %d
|
||||
|
||||
Deprecated: main(): Returning a non-string result from user output handler {closure:%s:%d} is deprecated in %s on line %d
|
||||
|
||||
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
|
||||
@@ -1,35 +0,0 @@
|
||||
--TEST--
|
||||
ob_start(): Check behaviour with deprecation when OOM triggers handler removal (handler returns non-stringable object + produces output)
|
||||
--INI--
|
||||
memory_limit=2M
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class NotStringable {
|
||||
public function __construct(public string $val) {}
|
||||
}
|
||||
|
||||
ob_start(function() {
|
||||
// We are out of memory, now trigger a deprecation
|
||||
echo "IN HANDLER\n";
|
||||
return new NotStringable("");
|
||||
});
|
||||
|
||||
$a = [];
|
||||
// trigger OOM in a resize operation
|
||||
while (1) {
|
||||
$a[] = 1;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: main(): Producing output from user output handler {closure:%s:%d} is deprecated in %s on line %d
|
||||
|
||||
Deprecated: main(): Returning a non-string result from user output handler {closure:%s:%d} is deprecated in %s on line %d
|
||||
|
||||
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
|
||||
|
||||
Fatal error: Uncaught Error: Object of class NotStringable could not be converted to string in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %s on line %d
|
||||
@@ -1,26 +0,0 @@
|
||||
--TEST--
|
||||
ob_start(): Check behaviour with deprecation when OOM triggers handler removal (handler returns true + produces output)
|
||||
--INI--
|
||||
memory_limit=2M
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
ob_start(function() {
|
||||
// We are out of memory, now trigger a deprecation
|
||||
echo "IN HANDLER\n";
|
||||
return true;
|
||||
});
|
||||
|
||||
$a = [];
|
||||
// trigger OOM in a resize operation
|
||||
while (1) {
|
||||
$a[] = 1;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: main(): Producing output from user output handler {closure:%s:%d} is deprecated in %s on line %d
|
||||
|
||||
Deprecated: main(): Returning a non-string result from user output handler {closure:%s:%d} is deprecated in %s on line %d
|
||||
|
||||
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
|
||||
@@ -1,26 +0,0 @@
|
||||
--TEST--
|
||||
ob_start(): Check behaviour with deprecation when OOM triggers handler removal (handler returns zero + produces output)
|
||||
--INI--
|
||||
memory_limit=2M
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
ob_start(function() {
|
||||
// We are out of memory, now trigger a deprecation
|
||||
echo "IN HANDLER\n";
|
||||
return 0;
|
||||
});
|
||||
|
||||
$a = [];
|
||||
// trigger OOM in a resize operation
|
||||
while (1) {
|
||||
$a[] = 1;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: main(): Producing output from user output handler {closure:%s:%d} is deprecated in %s on line %d
|
||||
|
||||
Deprecated: main(): Returning a non-string result from user output handler {closure:%s:%d} is deprecated in %s on line %d
|
||||
|
||||
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
|
||||
@@ -1,115 +0,0 @@
|
||||
--TEST--
|
||||
ob_start(): Check behaviour with multiple nested handlers with bad return values and output
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$log = [];
|
||||
|
||||
function return_given_string($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return $string;
|
||||
}
|
||||
|
||||
function return_empty_string($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return "";
|
||||
}
|
||||
|
||||
function return_false($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return false;
|
||||
}
|
||||
|
||||
function return_true($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return true;
|
||||
}
|
||||
|
||||
function return_null($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return null;
|
||||
}
|
||||
|
||||
function return_string($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return "I stole your output.";
|
||||
}
|
||||
|
||||
function return_zero($string) {
|
||||
global $log;
|
||||
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
|
||||
echo __FUNCTION__;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ob_start('return_given_string');
|
||||
ob_start('return_empty_string');
|
||||
ob_start('return_false');
|
||||
ob_start('return_true');
|
||||
ob_start('return_null');
|
||||
ob_start('return_string');
|
||||
ob_start('return_zero');
|
||||
|
||||
echo "Testing...";
|
||||
|
||||
ob_end_flush();
|
||||
ob_end_flush();
|
||||
ob_end_flush();
|
||||
ob_end_flush();
|
||||
ob_end_flush();
|
||||
ob_end_flush();
|
||||
ob_end_flush();
|
||||
|
||||
echo "\n\nLog:\n";
|
||||
echo implode("\n", $log);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: ob_end_flush(): Producing output from user output handler return_given_string is deprecated in %s on line %d0
|
||||
|
||||
Deprecated: ob_end_flush(): Producing output from user output handler return_empty_string is deprecated in %s on line %d9
|
||||
|
||||
|
||||
Log:
|
||||
return_zero: <<<Testing...>>>
|
||||
return_string: <<<
|
||||
Deprecated: ob_end_flush(): Producing output from user output handler return_zero is deprecated in %s on line %d
|
||||
|
||||
Deprecated: ob_end_flush(): Returning a non-string result from user output handler return_zero is deprecated in %s on line %d
|
||||
0>>>
|
||||
return_null: <<<
|
||||
Deprecated: ob_end_flush(): Producing output from user output handler return_string is deprecated in %s on line %d5
|
||||
I stole your output.>>>
|
||||
return_true: <<<
|
||||
Deprecated: ob_end_flush(): Producing output from user output handler return_null is deprecated in %s on line %d
|
||||
|
||||
Deprecated: ob_end_flush(): Returning a non-string result from user output handler return_null is deprecated in %s on line %d
|
||||
>>>
|
||||
return_false: <<<
|
||||
Deprecated: ob_end_flush(): Producing output from user output handler return_true is deprecated in %s on line %d
|
||||
|
||||
Deprecated: ob_end_flush(): Returning a non-string result from user output handler return_true is deprecated in %s on line %d
|
||||
>>>
|
||||
return_empty_string: <<<
|
||||
Deprecated: ob_end_flush(): Producing output from user output handler return_false is deprecated in %s on line %d
|
||||
|
||||
Deprecated: ob_end_flush(): Returning a non-string result from user output handler return_false is deprecated in %s on line %d
|
||||
|
||||
Deprecated: ob_end_flush(): Producing output from user output handler return_true is deprecated in %s on line %d
|
||||
|
||||
Deprecated: ob_end_flush(): Returning a non-string result from user output handler return_true is deprecated in %s on line %d
|
||||
return_false>>>
|
||||
return_given_string: <<<
|
||||
Deprecated: ob_end_flush(): Producing output from user output handler return_empty_string is deprecated in %s on line %d9
|
||||
>>>
|
||||
Reference in New Issue
Block a user