mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Merge branch 'PHP-8.4'
* PHP-8.4: Fix GH-15169: stack overflow when var serialization in ext/standard/var
This commit is contained in:
commit
a165f1fffc
4 changed files with 49 additions and 28 deletions
|
@ -27,13 +27,6 @@ class Test2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Test3 {
|
|
||||||
public function __sleep()
|
|
||||||
{
|
|
||||||
serialize($this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function replace() {
|
function replace() {
|
||||||
return preg_replace_callback('#.#', function () {
|
return preg_replace_callback('#.#', function () {
|
||||||
return replace();
|
return replace();
|
||||||
|
@ -52,12 +45,6 @@ try {
|
||||||
echo $e->getMessage(), "\n";
|
echo $e->getMessage(), "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
serialize(new Test3);
|
|
||||||
} catch (Error $e) {
|
|
||||||
echo $e->getMessage(), "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
replace();
|
replace();
|
||||||
} catch (Error $e) {
|
} catch (Error $e) {
|
||||||
|
@ -79,4 +66,3 @@ array(4) {
|
||||||
Maximum call stack size of %d bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion?
|
Maximum call stack size of %d bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion?
|
||||||
Maximum call stack size of %d bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion?
|
Maximum call stack size of %d bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion?
|
||||||
Maximum call stack size of %d bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion?
|
Maximum call stack size of %d bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion?
|
||||||
Maximum call stack size of %d bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion?
|
|
||||||
|
|
|
@ -25,13 +25,6 @@ class Test2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Test3 {
|
|
||||||
public function __sleep()
|
|
||||||
{
|
|
||||||
serialize($this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function replace() {
|
function replace() {
|
||||||
return preg_replace_callback('#.#', function () {
|
return preg_replace_callback('#.#', function () {
|
||||||
return replace();
|
return replace();
|
||||||
|
@ -51,12 +44,6 @@ $fiber = new Fiber(function (): void {
|
||||||
echo $e->getMessage(), "\n";
|
echo $e->getMessage(), "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
serialize(new Test3);
|
|
||||||
} catch (Error $e) {
|
|
||||||
echo $e->getMessage(), "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
replace();
|
replace();
|
||||||
} catch (Error $e) {
|
} catch (Error $e) {
|
||||||
|
@ -81,4 +68,3 @@ array(4) {
|
||||||
Maximum call stack size of %d bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion?
|
Maximum call stack size of %d bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion?
|
||||||
Maximum call stack size of %d bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion?
|
Maximum call stack size of %d bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion?
|
||||||
Maximum call stack size of %d bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion?
|
Maximum call stack size of %d bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion?
|
||||||
Maximum call stack size of %d bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion?
|
|
||||||
|
|
35
ext/standard/tests/serialize/gh15169.phpt
Normal file
35
ext/standard/tests/serialize/gh15169.phpt
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
--TEST--
|
||||||
|
GH-15169 (stack overflow when var serialization in ext/standard/var)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (ini_get('zend.max_allowed_stack_size') === false) {
|
||||||
|
die('skip No stack limit support');
|
||||||
|
}
|
||||||
|
if (getenv('SKIP_ASAN')) {
|
||||||
|
die('skip ASAN needs different stack limit setting due to more stack space usage');
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--INI--
|
||||||
|
zend.max_allowed_stack_size=512K
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
class Node
|
||||||
|
{
|
||||||
|
public $next;
|
||||||
|
}
|
||||||
|
$firstNode = new Node();
|
||||||
|
$node = $firstNode;
|
||||||
|
for ($i = 0; $i < 30000; $i++) {
|
||||||
|
$newNode = new Node();
|
||||||
|
$node->next = $newNode;
|
||||||
|
$node = $newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
serialize($firstNode);
|
||||||
|
} catch (Error $e) {
|
||||||
|
echo $e->getMessage(), "\n";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
Maximum call stack size reached. Infinite recursion?
|
|
@ -1033,6 +1033,15 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, HashTable *ht,
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
static zend_always_inline bool php_serialize_check_stack_limit(void)
|
||||||
|
{
|
||||||
|
#ifdef ZEND_CHECK_STACK_LIMIT
|
||||||
|
return zend_call_stack_overflowed(EG(stack_limit));
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_data_t var_hash, bool in_rcn_array, bool is_root) /* {{{ */
|
static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_data_t var_hash, bool in_rcn_array, bool is_root) /* {{{ */
|
||||||
{
|
{
|
||||||
zend_long var_already;
|
zend_long var_already;
|
||||||
|
@ -1042,6 +1051,11 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (UNEXPECTED(php_serialize_check_stack_limit())) {
|
||||||
|
zend_throw_error(NULL, "Maximum call stack size reached. Infinite recursion?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (var_hash && (var_already = php_add_var_hash(var_hash, struc, in_rcn_array))) {
|
if (var_hash && (var_already = php_add_var_hash(var_hash, struc, in_rcn_array))) {
|
||||||
if (var_already == -1) {
|
if (var_already == -1) {
|
||||||
/* Reference to an object that failed to serialize, replace with null. */
|
/* Reference to an object that failed to serialize, replace with null. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue