diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 71e0c56a51c8..cb48e6234371 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -861,6 +861,14 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_ } } +#ifdef ZEND_CHECK_STACK_LIMIT + if (UNEXPECTED(zend_call_stack_overflowed(EG(stack_limit)))) { + zend_call_stack_size_error(); + zend_release_fcall_info_cache(fci_cache); + return SUCCESS; + } +#endif + call = zend_vm_stack_push_call_frame(call_info, func, fci->param_count, object_or_called_scope); uint32_t consumed_args = fci->param_count ? fci->consumed_args : 0; diff --git a/ext/spl/tests/gh15672.phpt b/ext/spl/tests/gh15672.phpt new file mode 100644 index 000000000000..ff3feda46f7e --- /dev/null +++ b/ext/spl/tests/gh15672.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-15672 (MultipleIterator attached to itself overflows the C stack) +--SKIPIF-- + +--EXTENSIONS-- +zend_test +--INI-- +memory_limit=2G +zend.max_allowed_stack_size=512K +--FILE-- +attachIterator(new ArrayIterator([1, 2, 3]), "1"); +$m->attachIterator($m, 3); +foreach ($m as $key => $value) { +} +?> +--EXPECTREGEX-- +.*Maximum call stack size of \d+ bytes.*Infinite recursion\?.*thrown in .* on line \d+ diff --git a/ext/spl/tests/gh15911.phpt b/ext/spl/tests/gh15911.phpt new file mode 100644 index 000000000000..502b2baf616b --- /dev/null +++ b/ext/spl/tests/gh15911.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-15911 (AppendIterator appended to itself overflows the C stack) +--SKIPIF-- + +--EXTENSIONS-- +zend_test +--INI-- +memory_limit=2G +zend.max_allowed_stack_size=512K +--FILE-- +append($it); +foreach ($it as $v) { +} +?> +--EXPECTREGEX-- +.*Maximum call stack size of \d+ bytes.*Infinite recursion\?.*thrown in .* on line \d+