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

Fix GH-20583: Stack overflow in http_build_query via deep structures

Closes GH-20590.
This commit is contained in:
Niels Dossche
2025-11-25 18:58:40 +01:00
parent 27f17c3322
commit 292a7f73ba
3 changed files with 44 additions and 0 deletions

2
NEWS
View File

@@ -58,6 +58,8 @@ PHP NEWS
- Standard:
. Fix memory leak in array_diff() with custom type checks. (ndossche)
. Fixed bug GH-20583 (Stack overflow in http_build_query
via deep structures). (ndossche)
- Tidy:
. Fixed bug GH-20374 (PHP with tidy and custom-tags). (ndossche)

View File

@@ -92,6 +92,15 @@ static void php_url_encode_scalar(zval *scalar, smart_str *form_str,
}
}
static zend_always_inline bool php_url_check_stack_limit(void)
{
#ifdef ZEND_CHECK_STACK_LIMIT
return zend_call_stack_overflowed(EG(stack_limit));
#else
return false;
#endif
}
/* {{{ php_url_encode_hash */
PHPAPI void php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
const char *num_prefix, size_t num_prefix_len,
@@ -110,6 +119,12 @@ PHPAPI void php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
return;
}
/* Very deeply structured data could trigger a stack overflow, even without recursion. */
if (UNEXPECTED(php_url_check_stack_limit())) {
zend_throw_error(NULL, "Maximum call stack size reached.");
return;
}
if (!arg_sep) {
arg_sep = zend_ini_str("arg_separator.output", strlen("arg_separator.output"), false);
if (ZSTR_LEN(arg_sep) == 0) {

View File

@@ -0,0 +1,27 @@
--TEST--
GH-20583 (Stack overflow in http_build_query via deep structures)
--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
$a = null;
for ($i = 0; $i < 5000; $i++) {
$a = [$i => $a];
}
try {
http_build_query($a, 'p');
} catch (Throwable $e) {
echo $e::class, ": ", $e->getMessage(), "\n";
}
?>
--EXPECT--
Error: Maximum call stack size reached.