Limit stack size (#9104)

This commit is contained in:
Arnaud Le Blanc 2022-12-16 08:44:26 -08:00 committed by GitHub
parent dc54e04ed4
commit a11c8a3039
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 1844 additions and 12 deletions

View file

@ -28,6 +28,7 @@ environment:
#PDO_MYSQL_TEST_PASS: Password12! #PDO_MYSQL_TEST_PASS: Password12!
#PGSQL_TEST_CONNSTR: "host=127.0.0.1 dbname=test port=5432 user=postgres password=Password12!" #PGSQL_TEST_CONNSTR: "host=127.0.0.1 dbname=test port=5432 user=postgres password=Password12!"
#PDO_PGSQL_TEST_DSN: "pgsql:host=127.0.0.1 port=5432 dbname=test user=postgres password=Password12!" #PDO_PGSQL_TEST_DSN: "pgsql:host=127.0.0.1 port=5432 dbname=test user=postgres password=Password12!"
STACK_LIMIT_DEFAULTS_CHECK: 1
#build permutations #build permutations
matrix: matrix:
- THREAD_SAFE: 0 - THREAD_SAFE: 0

View file

@ -201,4 +201,5 @@ freebsd_task:
tests_script: tests_script:
- export SKIP_IO_CAPTURE_TESTS=1 - export SKIP_IO_CAPTURE_TESTS=1
- export CI_NO_IPV6=1 - export CI_NO_IPV6=1
- export STACK_LIMIT_DEFAULTS_CHECK=1
- sapi/cli/php run-tests.php -P -q -j2 -g FAIL,BORK,LEAK,XLEAK --no-progress --offline --show-diff --show-slow 1000 --set-timeout 120 -d zend_extension=opcache.so - sapi/cli/php run-tests.php -P -q -j2 -g FAIL,BORK,LEAK,XLEAK --no-progress --offline --show-diff --show-slow 1000 --set-timeout 120 -d zend_extension=opcache.so

View file

@ -30,6 +30,7 @@ runs:
export PDO_OCI_TEST_DSN="oci:dbname=localhost/XEPDB1;charset=AL32UTF8" export PDO_OCI_TEST_DSN="oci:dbname=localhost/XEPDB1;charset=AL32UTF8"
export SKIP_IO_CAPTURE_TESTS=1 export SKIP_IO_CAPTURE_TESTS=1
export TEST_PHP_JUNIT=junit.out.xml export TEST_PHP_JUNIT=junit.out.xml
export STACK_LIMIT_DEFAULTS_CHECK=1
sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \ sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \
-j$(/usr/bin/nproc) \ -j$(/usr/bin/nproc) \
-g FAIL,BORK,LEAK,XLEAK \ -g FAIL,BORK,LEAK,XLEAK \

View file

@ -15,6 +15,7 @@ runs:
export SKIP_IO_CAPTURE_TESTS=1 export SKIP_IO_CAPTURE_TESTS=1
export CI_NO_IPV6=1 export CI_NO_IPV6=1
export TEST_PHP_JUNIT=junit.out.xml export TEST_PHP_JUNIT=junit.out.xml
export STACK_LIMIT_DEFAULTS_CHECK=1
sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \ sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \
-j$(sysctl -n hw.ncpu) \ -j$(sysctl -n hw.ncpu) \
-g FAIL,BORK,LEAK,XLEAK \ -g FAIL,BORK,LEAK,XLEAK \

View file

@ -146,7 +146,37 @@ _LT_AC_TRY_DLOPEN_SELF([
]) ])
dnl Checks for library functions. dnl Checks for library functions.
AC_CHECK_FUNCS(getpid kill sigsetjmp) AC_CHECK_FUNCS(getpid kill sigsetjmp pthread_getattr_np pthread_attr_get_np pthread_get_stackaddr_np pthread_attr_getstack gettid)
dnl Test whether the stack grows downwards
dnl Assumes contiguous stack
AC_MSG_CHECKING(whether the stack grows downwards)
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdint.h>
int (*volatile f)(uintptr_t);
int stack_grows_downwards(uintptr_t arg) {
int local;
return (uintptr_t)&local < arg;
}
int main() {
int local;
f = stack_grows_downwards;
return f((uintptr_t)&local) ? 0 : 1;
}
]])], [
AC_DEFINE([ZEND_STACK_GROWS_DOWNWARDS], 1, [Define if the stack grows downwards])
AC_DEFINE([ZEND_CHECK_STACK_LIMIT], 1, [Define if checking the stack limit is supported])
AC_MSG_RESULT(yes)
], [
AC_MSG_RESULT(no)
], [
AC_MSG_RESULT(no)
])
ZEND_CHECK_FLOAT_PRECISION ZEND_CHECK_FLOAT_PRECISION
]) ])

View file

@ -0,0 +1,77 @@
--TEST--
Stack limit 001 - Stack limit checks with max_allowed_stack_size detection
--EXTENSIONS--
zend_test
--INI--
; The test may use a large amount of memory on systems with a large stack limit
memory_limit=2G
--FILE--
<?php
var_dump(zend_test_zend_call_stack_get());
class Test1 {
public function __destruct() {
new Test1;
}
}
class Test2 {
public function __clone() {
clone $this;
}
}
class Test3 {
public function __sleep()
{
serialize($this);
}
}
function replace() {
return preg_replace_callback('#.#', function () {
return replace();
}, 'x');
}
try {
new Test1;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
clone new Test2;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
serialize(new Test3);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
replace();
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECTF--
array(4) {
["base"]=>
string(%d) "0x%x"
["max_size"]=>
string(%d) "0x%x"
["position"]=>
string(%d) "0x%x"
["EG(stack_limit)"]=>
string(%d) "0x%x"
}
Maximum call stack size of %d bytes reached. Infinite recursion?
Maximum call stack size of %d bytes reached. Infinite recursion?
Maximum call stack size of %d bytes reached. Infinite recursion?
Maximum call stack size of %d bytes reached. Infinite recursion?

View file

@ -0,0 +1,80 @@
--TEST--
Stack limit 002 - Stack limit checks with max_allowed_stack_size detection (fibers)
--EXTENSIONS--
zend_test
--INI--
fiber.stack_size=512k
--FILE--
<?php
var_dump(zend_test_zend_call_stack_get());
class Test1 {
public function __destruct() {
new Test1;
}
}
class Test2 {
public function __clone() {
clone $this;
}
}
class Test3 {
public function __sleep()
{
serialize($this);
}
}
function replace() {
return preg_replace_callback('#.#', function () {
return replace();
}, 'x');
}
$fiber = new Fiber(function (): void {
try {
new Test1;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
clone new Test2;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
serialize(new Test3);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
replace();
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
});
$fiber->start();
?>
--EXPECTF--
array(4) {
["base"]=>
string(%d) "0x%x"
["max_size"]=>
string(%d) "0x%x"
["position"]=>
string(%d) "0x%x"
["EG(stack_limit)"]=>
string(%d) "0x%x"
}
Maximum call stack size of %d bytes reached. Infinite recursion?
Maximum call stack size of %d bytes reached. Infinite recursion?
Maximum call stack size of %d bytes reached. Infinite recursion?
Maximum call stack size of %d bytes reached. Infinite recursion?

View file

@ -0,0 +1,62 @@
--TEST--
Stack limit 003 - Stack limit checks with fixed max_allowed_stack_size
--EXTENSIONS--
zend_test
--INI--
zend.max_allowed_stack_size=128K
--FILE--
<?php
var_dump(zend_test_zend_call_stack_get());
class Test1 {
public function __destruct() {
new Test1;
}
}
class Test2 {
public function __clone() {
clone $this;
}
}
function replace() {
return preg_replace_callback('#.#', function () {
return replace();
}, 'x');
}
try {
new Test1;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
clone new Test2;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
replace();
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECTF--
array(4) {
["base"]=>
string(%d) "0x%x"
["max_size"]=>
string(%d) "0x%x"
["position"]=>
string(%d) "0x%x"
["EG(stack_limit)"]=>
string(%d) "0x%x"
}
Maximum call stack size of %d bytes reached. Infinite recursion?
Maximum call stack size of %d bytes reached. Infinite recursion?
Maximum call stack size of %d bytes reached. Infinite recursion?

View file

@ -0,0 +1,50 @@
--TEST--
Stack limit 004 - Stack limit checks with fixed max_allowed_stack_size (fibers)
--EXTENSIONS--
zend_test
--FILE--
<?php
var_dump(zend_test_zend_call_stack_get());
class Test1 {
public function __destruct() {
new Test1;
}
}
$callback = function (): int {
try {
new Test1;
} catch (Error $e) {
return count($e->getTrace());
}
throw new \Exception();
};
ini_set('fiber.stack_size', '400K');
$fiber = new Fiber($callback);
$fiber->start();
$depth1 = $fiber->getReturn();
ini_set('fiber.stack_size', '200K');
$fiber = new Fiber($callback);
$fiber->start();
$depth2 = $fiber->getReturn();
var_dump($depth1 > $depth2);
?>
--EXPECTF--
array(4) {
["base"]=>
string(%d) "0x%x"
["max_size"]=>
string(%d) "0x%x"
["position"]=>
string(%d) "0x%x"
["EG(stack_limit)"]=>
string(%d) "0x%x"
}
bool(true)

View file

@ -0,0 +1,64 @@
--TEST--
Stack limit 005 - Internal stack limit check in zend_compile_expr()
--EXTENSIONS--
zend_test
--INI--
zend.max_allowed_stack_size=128K
--FILE--
<?php
$test
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
;
--EXPECTF--
Fatal error: Maximum call stack size of %d bytes reached during compilation. Try splitting expression in %s on line %d

View file

@ -0,0 +1,320 @@
--TEST--
Stack limit 006 - env size affects __libc_stack_end
--EXTENSIONS--
zend_test
--INI--
; TODO
memory_limit=2G
--ENV--
ENV001=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV002=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV003=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV004=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV005=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV006=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV007=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV008=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV009=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV010=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV011=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV012=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV013=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV014=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV015=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV016=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV017=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV018=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV019=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV020=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV021=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV022=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV023=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV024=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV025=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV026=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV027=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV028=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV029=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV030=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV031=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV032=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV033=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV034=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV035=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV036=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV037=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV038=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV039=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV040=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV041=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV042=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV043=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV044=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV045=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV046=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV047=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV048=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV049=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV050=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV051=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV052=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV053=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV054=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV055=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV056=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV057=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV058=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV059=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV060=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV061=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV062=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV063=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV064=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV065=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV066=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV067=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV068=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV069=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV070=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV071=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV072=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV073=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV074=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV075=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV076=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV077=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV078=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV079=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV080=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV081=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV082=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV083=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV084=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV085=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV086=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV087=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV088=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV089=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV090=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV091=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV092=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV093=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV094=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV095=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV096=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV097=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV098=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV099=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV100=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV101=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV102=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV103=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV104=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV105=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV106=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV107=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV108=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV109=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV110=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV111=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV112=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV113=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV114=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV115=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV116=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV117=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV118=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV119=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV120=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV121=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV122=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV123=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV124=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV125=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV126=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV127=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV128=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV129=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV130=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV131=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV132=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV133=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV134=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV135=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV136=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV137=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV138=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV139=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV140=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV141=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV142=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV143=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV144=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV145=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV146=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV147=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV148=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV149=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV150=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV151=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV152=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV153=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV154=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV155=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV156=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV157=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV158=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV159=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV160=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV161=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV162=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV163=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV164=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV165=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV166=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV167=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV168=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV169=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV170=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV171=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV172=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV173=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV174=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV175=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV176=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV177=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV178=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV179=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV180=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV181=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV182=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV183=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV184=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV185=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV186=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV187=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV188=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV189=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV190=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV191=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV192=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV193=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV194=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV195=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV196=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV197=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV198=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV199=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV200=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV201=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV202=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV203=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV204=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV205=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV206=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV207=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV208=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV209=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV210=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV211=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV212=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV213=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV214=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV215=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV216=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV217=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV218=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV219=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV220=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV221=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV222=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV223=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV224=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV225=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV226=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV227=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV228=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV229=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV230=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV231=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV232=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV233=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV234=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV235=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV236=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV237=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV238=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV239=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV240=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV241=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV242=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV243=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV244=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV245=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV246=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV247=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV248=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV249=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV250=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV251=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV252=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV253=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV254=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV255=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENV256=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
--FILE--
<?php
var_dump(zend_test_zend_call_stack_get());
class Test1 {
public function __destruct() {
new Test1;
}
}
class Test2 {
public function __clone() {
clone $this;
}
}
function replace() {
return preg_replace_callback('#.#', function () {
return replace();
}, 'x');
}
try {
new Test1;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
clone new Test2;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
replace();
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECTF--
array(4) {
["base"]=>
string(%d) "0x%x"
["max_size"]=>
string(%d) "0x%x"
["position"]=>
string(%d) "0x%x"
["EG(stack_limit)"]=>
string(%d) "0x%x"
}
Maximum call stack size of %d bytes reached. Infinite recursion?
Maximum call stack size of %d bytes reached. Infinite recursion?
Maximum call stack size of %d bytes reached. Infinite recursion?

View file

@ -0,0 +1,41 @@
--TEST--
Stack limit 007 - Exception handling
--EXTENSIONS--
zend_test
--INI--
zend.max_allowed_stack_size=128K
--FILE--
<?php
var_dump(zend_test_zend_call_stack_get());
function replace() {
return preg_replace_callback('#.#', function () {
try {
$tryExecuted = true;
return replace();
} catch (Error $e) {
echo $e->getMessage(), "\n";
// We should not enter the catch block if we haven't executed at
// least one op in the try block
printf("Try executed: %d\n", $tryExecuted ?? 0);
}
}, 'x');
}
replace();
?>
--EXPECTF--
array(4) {
["base"]=>
string(%d) "0x%x"
["max_size"]=>
string(%d) "0x%x"
["position"]=>
string(%d) "0x%x"
["EG(stack_limit)"]=>
string(%d) "0x%x"
}
Maximum call stack size of %d bytes reached. Infinite recursion?
Try executed: 1

View file

@ -0,0 +1,54 @@
--TEST--
Stack limit 008 - Exception handling
--EXTENSIONS--
zend_test
--INI--
zend.max_allowed_stack_size=128K
--FILE--
<?php
var_dump(zend_test_zend_call_stack_get());
function replace() {
return preg_replace_callback('#.#', function () {
try {
return replace();
} catch (Error $e) {
echo "Will throw:\n";
try {
return replace2();
} catch (Error $e) {
echo $e->getMessage();
}
}
}, 'x');
}
function replace2() {
return preg_replace_callback('#.#', function () {
try {
return '';
} finally {
// We should not enter the finally block if we haven't executed at
// least one op in the try block
echo "Finally block: This should not execute\n";
}
}, 'x');
}
replace();
?>
--EXPECTF--
array(4) {
["base"]=>
string(%d) "0x%x"
["max_size"]=>
string(%d) "0x%x"
["position"]=>
string(%d) "0x%x"
["EG(stack_limit)"]=>
string(%d) "0x%x"
}
Will throw:
Maximum call stack size of %d bytes reached. Infinite recursion?

View file

@ -0,0 +1,24 @@
--TEST--
Stack limit 009 - Check that we can actually use all the stack
--EXTENSIONS--
zend_test
--FILE--
<?php
var_dump(zend_test_zend_call_stack_get());
var_dump(zend_test_zend_call_stack_use_all());
?>
--EXPECTF--
array(4) {
["base"]=>
string(%d) "0x%x"
["max_size"]=>
string(%d) "0x%x"
["position"]=>
string(%d) "0x%x"
["EG(stack_limit)"]=>
string(%d) "0x%x"
}
int(%d)

View file

@ -0,0 +1,48 @@
--TEST--
Stack limit 010 - Check stack size detection against known defaults
--EXTENSIONS--
zend_test
--SKIPIF--
<?php
if (!getenv('STACK_LIMIT_DEFAULTS_CHECK')) { die('skip STACK_LIMIT_DEFAULTS_CHECK not set'); }
?>
--FILE--
<?php
$stack = zend_test_zend_call_stack_get();
var_dump($stack);
$expectedMaxSize = match(php_uname('s')) {
'Darwin' => 8*1024*1024,
'FreeBSD' => match(php_uname('m')) {
'amd64' => 512*1024*1024 - 4096,
'i386' => 64*1024*1024 - 4096,
},
'Linux' => match (getenv('GITHUB_ACTIONS')) {
'true' => 16*1024*1024, // https://github.com/actions/runner-images/pull/3328
default => 8*1024*1024,
},
'Windows NT' => 67108864 - 4*4096, // Set by sapi/cli/config.w32
};
printf("Expected max_size: 0x%x\n", $expectedMaxSize);
printf("Actual max_size: %s\n", $stack['max_size']);
var_dump($stack['max_size'] === sprintf('0x%x', $expectedMaxSize));
?>
--EXPECTF--
array(4) {
["base"]=>
string(%d) "0x%x"
["max_size"]=>
string(%d) "0x%x"
["position"]=>
string(%d) "0x%x"
["EG(stack_limit)"]=>
string(%d) "0x%x"
}
Expected max_size: 0x%x
Actual max_size: 0x%x
bool(true)

View file

@ -0,0 +1,48 @@
--TEST--
Stack limit 011 - Stack limit exhaustion during unwinding
--EXTENSIONS--
zend_test
--INI--
zend.max_allowed_stack_size=128K
--FILE--
<?php
var_dump(zend_test_zend_call_stack_get());
class Test1 {
public function __destruct() {
new Test1;
}
}
function replace() {
return preg_replace_callback('#.#', function () {
try {
replace();
} finally {
new Test1();
}
}, 'x');
}
try {
replace();
} catch (Error $e) {
echo $e->getMessage(), "\n";
echo 'Previous: ', $e->getPrevious()->getMessage(), "\n";
}
?>
--EXPECTF--
array(4) {
["base"]=>
string(%d) "0x%x"
["max_size"]=>
string(%d) "0x%x"
["position"]=>
string(%d) "0x%x"
["EG(stack_limit)"]=>
string(%d) "0x%x"
}
Maximum call stack size of %d bytes reached. Infinite recursion?
Previous: Maximum call stack size of %d bytes reached. Infinite recursion?

View file

@ -0,0 +1,54 @@
<?php
$test
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
->f()->f()->f()->f()->f()->f()->f()->f()->f()->f()
;

View file

@ -0,0 +1,37 @@
--TEST--
Stack limit 012 - Stack limit exhaustion during unwinding
--EXTENSIONS--
zend_test
--INI--
zend.max_allowed_stack_size=128K
--FILE--
<?php
var_dump(zend_test_zend_call_stack_get());
function replace() {
return preg_replace_callback('#.#', function () {
try {
replace();
} finally {
require __DIR__ . '/stack_limit_012.inc';
}
}, 'x');
}
replace();
?>
--EXPECTF--
array(4) {
["base"]=>
string(%d) "0x%x"
["max_size"]=>
string(%d) "0x%x"
["position"]=>
string(%d) "0x%x"
["EG(stack_limit)"]=>
string(%d) "0x%x"
}
Fatal error: Maximum call stack size of %d bytes reached during compilation. Try splitting expression in %s on line %d

View file

@ -35,6 +35,7 @@
#include "zend_attributes.h" #include "zend_attributes.h"
#include "zend_observer.h" #include "zend_observer.h"
#include "zend_fibers.h" #include "zend_fibers.h"
#include "zend_call_stack.h"
#include "Optimizer/zend_optimizer.h" #include "Optimizer/zend_optimizer.h"
static size_t global_map_ptr_last = 0; static size_t global_map_ptr_last = 0;
@ -173,6 +174,52 @@ static ZEND_INI_MH(OnSetExceptionStringParamMaxLen) /* {{{ */
} }
/* }}} */ /* }}} */
#ifdef ZEND_CHECK_STACK_LIMIT
static ZEND_INI_MH(OnUpdateMaxAllowedStackSize) /* {{{ */
{
zend_long size = zend_ini_parse_quantity_warn(new_value, entry->name);
if (size < ZEND_MAX_ALLOWED_STACK_SIZE_UNCHECKED) {
zend_error(E_WARNING, "Invalid \"%s\" setting. Value must be >= %d, but got " ZEND_LONG_FMT,
ZSTR_VAL(entry->name), ZEND_MAX_ALLOWED_STACK_SIZE_UNCHECKED, size);
return FAILURE;
}
EG(max_allowed_stack_size) = size;
return SUCCESS;
}
/* }}} */
static ZEND_INI_MH(OnUpdateReservedStackSize) /* {{{ */
{
zend_ulong size = zend_ini_parse_uquantity_warn(new_value, entry->name);
/* Min value accounts for alloca, PCRE2 START_FRAMES_SIZE, and some buffer
* for normal function calls.
* We could reduce this on systems without alloca if we also add stack size
* checks before pcre2_match(). */
#ifdef ZEND_ALLOCA_MAX_SIZE
zend_ulong min = ZEND_ALLOCA_MAX_SIZE + 16*1024;
#else
zend_ulong min = 32*1024;
#endif
if (size == 0) {
size = min;
} else if (size < min) {
zend_error(E_WARNING, "Invalid \"%s\" setting. Value must be >= " ZEND_ULONG_FMT ", but got " ZEND_ULONG_FMT "\n",
ZSTR_VAL(entry->name), min, size);
return FAILURE;
}
EG(reserved_stack_size) = size;
return SUCCESS;
}
/* }}} */
#endif /* ZEND_CHECK_STACK_LIMIT */
static ZEND_INI_MH(OnUpdateFiberStackSize) /* {{{ */ static ZEND_INI_MH(OnUpdateFiberStackSize) /* {{{ */
{ {
if (new_value) { if (new_value) {
@ -203,6 +250,12 @@ ZEND_INI_BEGIN()
STD_ZEND_INI_BOOLEAN("zend.exception_ignore_args", "0", ZEND_INI_ALL, OnUpdateBool, exception_ignore_args, zend_executor_globals, executor_globals) STD_ZEND_INI_BOOLEAN("zend.exception_ignore_args", "0", ZEND_INI_ALL, OnUpdateBool, exception_ignore_args, zend_executor_globals, executor_globals)
STD_ZEND_INI_ENTRY("zend.exception_string_param_max_len", "15", ZEND_INI_ALL, OnSetExceptionStringParamMaxLen, exception_string_param_max_len, zend_executor_globals, executor_globals) STD_ZEND_INI_ENTRY("zend.exception_string_param_max_len", "15", ZEND_INI_ALL, OnSetExceptionStringParamMaxLen, exception_string_param_max_len, zend_executor_globals, executor_globals)
STD_ZEND_INI_ENTRY("fiber.stack_size", NULL, ZEND_INI_ALL, OnUpdateFiberStackSize, fiber_stack_size, zend_executor_globals, executor_globals) STD_ZEND_INI_ENTRY("fiber.stack_size", NULL, ZEND_INI_ALL, OnUpdateFiberStackSize, fiber_stack_size, zend_executor_globals, executor_globals)
#ifdef ZEND_CHECK_STACK_LIMIT
/* The maximum allowed call stack size. 0: auto detect, -1: no limit. For fibers, this is fiber.stack_size. */
STD_ZEND_INI_ENTRY("zend.max_allowed_stack_size", "0", ZEND_INI_SYSTEM, OnUpdateMaxAllowedStackSize, max_allowed_stack_size, zend_executor_globals, executor_globals)
/* Substracted from the max allowed stack size, as a buffer, when checking for overflow. 0: auto detect. */
STD_ZEND_INI_ENTRY("zend.reserved_stack_size", "0", ZEND_INI_SYSTEM, OnUpdateReservedStackSize, reserved_stack_size, zend_executor_globals, executor_globals)
#endif
ZEND_INI_END() ZEND_INI_END()
@ -796,6 +849,10 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{
executor_globals->record_errors = false; executor_globals->record_errors = false;
executor_globals->num_errors = 0; executor_globals->num_errors = 0;
executor_globals->errors = NULL; executor_globals->errors = NULL;
#ifdef ZEND_CHECK_STACK_LIMIT
executor_globals->stack_limit = (void*)0;
executor_globals->stack_base = (void*)0;
#endif
} }
/* }}} */ /* }}} */
@ -817,6 +874,9 @@ static void zend_new_thread_end_handler(THREAD_T thread_id) /* {{{ */
{ {
zend_copy_ini_directives(); zend_copy_ini_directives();
zend_ini_refresh_caches(ZEND_INI_STAGE_STARTUP); zend_ini_refresh_caches(ZEND_INI_STAGE_STARTUP);
#ifdef ZEND_CHECK_STACK_LIMIT
zend_call_stack_init();
#endif
} }
/* }}} */ /* }}} */
#endif #endif
@ -982,7 +1042,7 @@ void zend_startup(zend_utility_functions *utility_functions) /* {{{ */
CG(map_ptr_base) = ZEND_MAP_PTR_BIASED_BASE(NULL); CG(map_ptr_base) = ZEND_MAP_PTR_BIASED_BASE(NULL);
CG(map_ptr_size) = 0; CG(map_ptr_size) = 0;
CG(map_ptr_last) = 0; CG(map_ptr_last) = 0;
#endif #endif /* ZTS */
EG(error_reporting) = E_ALL & ~E_NOTICE; EG(error_reporting) = E_ALL & ~E_NOTICE;
zend_interned_strings_init(); zend_interned_strings_init();
@ -1077,6 +1137,10 @@ zend_result zend_post_startup(void) /* {{{ */
global_map_ptr_last = CG(map_ptr_last); global_map_ptr_last = CG(map_ptr_last);
#endif #endif
#ifdef ZEND_CHECK_STACK_LIMIT
zend_call_stack_init();
#endif
return SUCCESS; return SUCCESS;
} }
/* }}} */ /* }}} */

457
Zend/zend_call_stack.c Normal file
View file

@ -0,0 +1,457 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Arnaud Le Blanc <arnaud.lb@gmail.com> |
+----------------------------------------------------------------------+
*/
/* Inspired from Chromium's stack_util.cc */
#include "zend.h"
#include "zend_globals.h"
#include "zend_portability.h"
#include "zend_call_stack.h"
#include <stdint.h>
#ifdef ZEND_WIN32
# include <processthreadsapi.h>
# include <memoryapi.h>
#else /* ZEND_WIN32 */
# include <sys/resource.h>
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
# ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
# endif
#endif /* ZEND_WIN32 */
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
# include <pthread.h>
#endif
#ifdef __FreeBSD__
# include <pthread_np.h>
# include <sys/mman.h>
# include <sys/sysctl.h>
# include <sys/user.h>
#endif
#ifdef __linux__
#include <sys/syscall.h>
#endif
#ifdef ZEND_CHECK_STACK_LIMIT
/* Called once per process or thread */
ZEND_API void zend_call_stack_init(void) {
if (!zend_call_stack_get(&EG(call_stack))) {
EG(call_stack) = (zend_call_stack){0};
}
switch (EG(max_allowed_stack_size)) {
case ZEND_MAX_ALLOWED_STACK_SIZE_DETECT: {
void *base = EG(call_stack).base;
size_t size = EG(call_stack).max_size;
if (UNEXPECTED(base == (void*)0)) {
base = zend_call_stack_position();
size = zend_call_stack_default_size();
/* base is not the actual stack base */
size -= 32 * 1024;
}
EG(stack_base) = base;
EG(stack_limit) = zend_call_stack_limit(base, size, EG(reserved_stack_size));
break;
}
case ZEND_MAX_ALLOWED_STACK_SIZE_UNCHECKED: {
EG(stack_base) = (void*)0;
EG(stack_limit) = (void*)0;
break;
}
default: {
ZEND_ASSERT(EG(max_allowed_stack_size) > 0);
void *base = EG(call_stack).base;
if (UNEXPECTED(base == (void*)0)) {
base = zend_call_stack_position();
}
EG(stack_base) = base;
EG(stack_limit) = zend_call_stack_limit(base, EG(max_allowed_stack_size), EG(reserved_stack_size));
break;
}
}
}
#ifdef __linux__
static bool zend_call_stack_is_main_thread(void) {
# ifdef HAVE_GETTID
return getpid() == gettid();
# else
return getpid() == syscall(SYS_gettid);
# endif
}
# ifdef HAVE_PTHREAD_GETATTR_NP
static bool zend_call_stack_get_linux_pthread(zend_call_stack *stack)
{
pthread_attr_t attr;
int error;
void *addr;
size_t max_size;
/* pthread_getattr_np() will return bogus values for the main thread with
* musl or with some old glibc versions */
ZEND_ASSERT(!zend_call_stack_is_main_thread());
error = pthread_getattr_np(pthread_self(), &attr);
if (error) {
return false;
}
error = pthread_attr_getstack(&attr, &addr, &max_size);
if (error) {
return false;
}
# if defined(__GLIBC__) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 8))
{
size_t guard_size;
/* In glibc prior to 2.8, addr and size include the guard pages */
error = pthread_attr_getguardsize(&attr, &guard_size);
if (error) {
return false;
}
addr = (int8_t*)addr + guard_size;
max_size -= guard_size;
}
# endif /* glibc < 2.8 */
stack->base = (int8_t*)addr + max_size;
stack->max_size = max_size;
return true;
}
# else /* HAVE_PTHREAD_GETATTR_NP */
static bool zend_call_stack_get_linux_pthread(zend_call_stack *stack)
{
return false;
}
# endif /* HAVE_PTHREAD_GETATTR_NP */
static bool zend_call_stack_get_linux_proc_maps(zend_call_stack *stack)
{
FILE *f;
char buffer[4096];
uintptr_t addr_on_stack = (uintptr_t)&buffer;
uintptr_t start, end, prev_end = 0;
size_t max_size;
bool found = false;
struct rlimit rlim;
int error;
/* This method is relevant only for the main thread */
ZEND_ASSERT(zend_call_stack_is_main_thread());
/* Scan the process memory mappings to find the one containing the stack.
*
* The end of the stack mapping is the base of the stack. The start is
* adjusted by the kernel as the stack grows. The maximum stack size is
* determined by RLIMIT_STACK and the previous mapping.
*
*
* ^ Higher addresses ^
* : :
* : :
* Mapping end --> |-------------------| <-- Stack base (stack start)
* | | ^
* | Stack Mapping | | Stack size
* | | v
* Mapping start --> |-------------------| <-- Current stack end
* (adjusted : :
* downwards as the . .
* stack grows) : :
* |-------------------|
* | Some Mapping | The previous mapping may prevent
* |-------------------| stack growth
* : :
* : :
* v Lower addresses v
*/
f = fopen("/proc/self/maps", "r");
if (!f) {
return false;
}
while (fgets(buffer, sizeof(buffer), f) && sscanf(buffer, "%" SCNxPTR "-%" SCNxPTR, &start, &end) == 2) {
if (start <= addr_on_stack && end >= addr_on_stack) {
found = true;
break;
}
prev_end = end;
}
fclose(f);
if (!found) {
return false;
}
error = getrlimit(RLIMIT_STACK, &rlim);
if (error || rlim.rlim_cur == RLIM_INFINITY) {
return false;
}
max_size = rlim.rlim_cur;
/* Previous mapping may prevent the stack from growing */
if (end - max_size < prev_end) {
max_size = prev_end - end;
}
stack->base = (void*)end;
stack->max_size = max_size;
return true;
}
static bool zend_call_stack_get_linux(zend_call_stack *stack)
{
if (zend_call_stack_is_main_thread()) {
return zend_call_stack_get_linux_proc_maps(stack);
}
return zend_call_stack_get_linux_pthread(stack);
}
#else /* __linux__ */
static bool zend_call_stack_get_linux(zend_call_stack *stack)
{
return false;
}
#endif /* __linux__ */
#ifdef __FreeBSD__
static bool zend_call_stack_is_main_thread(void)
{
int is_main = pthread_main_np();
return is_main == -1 || is_main == 1;
}
# if defined(HAVE_PTHREAD_ATTR_GET_NP) && defined(HAVE_PTHREAD_ATTR_GET_STACK)
static bool zend_call_stack_get_freebsd_pthread(zend_call_stack *stack)
{
pthread_attr_t attr;
int error;
void *addr;
size_t max_size;
size_t guard_size;
/* pthread will return bogus values for the main thread */
ZEND_ASSERT(!zend_call_stack_is_main_thread());
pthread_attr_init(&attr);
error = pthread_attr_get_np(pthread_self(), &attr);
if (error) {
goto fail;
}
error = pthread_attr_getstack(&attr, &addr, &max_size);
if (error) {
goto fail;
}
stack->base = (int8_t*)addr + max_size;
stack->max_size = max_size;
pthread_attr_destroy(&attr);
return true;
fail:
pthread_attr_destroy(&attr);
return false;
}
# else /* defined(HAVE_PTHREAD_ATTR_GET_NP) && defined(HAVE_PTHREAD_ATTR_GET_STACK) */
static bool zend_call_stack_get_freebsd_pthread(zend_call_stack *stack)
{
return false;
}
# endif /* defined(HAVE_PTHREAD_ATTR_GET_NP) && defined(HAVE_PTHREAD_ATTR_GET_STACK) */
static bool zend_call_stack_get_freebsd_sysctl(zend_call_stack *stack)
{
void *stack_base;
int mib[2] = {CTL_KERN, KERN_USRSTACK};
size_t len = sizeof(stack_base);
struct rlimit rlim;
/* This method is relevant only for the main thread */
ZEND_ASSERT(zend_call_stack_is_main_thread());
if (sysctl(mib, sizeof(mib)/sizeof(*mib), &stack_base, &len, NULL, 0) != 0) {
return false;
}
if (getrlimit(RLIMIT_STACK, &rlim) != 0) {
return false;
}
if (rlim.rlim_cur == RLIM_INFINITY) {
return false;
}
size_t guard_size = getpagesize();
stack->base = stack_base;
stack->max_size = rlim.rlim_cur - guard_size;
return true;
}
static bool zend_call_stack_get_freebsd(zend_call_stack *stack)
{
if (zend_call_stack_is_main_thread()) {
return zend_call_stack_get_freebsd_sysctl(stack);
}
return zend_call_stack_get_freebsd_pthread(stack);
}
#else
static bool zend_call_stack_get_freebsd(zend_call_stack *stack)
{
return false;
}
#endif /* __FreeBSD__ */
#ifdef ZEND_WIN32
static bool zend_call_stack_get_win32(zend_call_stack *stack)
{
ULONG_PTR low_limit, high_limit;
ULONG size;
MEMORY_BASIC_INFORMATION guard_region = {0}, uncommitted_region = {0};
size_t result_size, page_size;
/* The stack consists of three regions: committed, guard, and uncommitted.
* Memory is committed when the guard region is accessed. If only one page
* is left in the uncommitted region, a stack overflow error is raised
* instead.
*
* The total useable stack size is the size of the committed and uncommitted
* regions less one page.
*
* http://blogs.msdn.com/b/satyem/archive/2012/08/13/thread-s-stack-memory-management.aspx
* https://learn.microsoft.com/en-us/windows/win32/procthread/thread-stack-size
*
* ^ Higher addresses ^
* : :
* : :
* high_limit --> |--------------------|
* ^ | |
* | | Committed region |
* | | |
* | |------------------- | <-- guard_region.BaseAddress
* reserved | | | + guard_region.RegionSize
* size | | Guard region |
* | | |
* | |--------------------| <-- guard_region.BaseAddress,
* | | | uncommitted_region.BaseAddress
* | | Uncommitted region | + uncommitted_region.RegionSize
* v | |
* low_limit --> |------------------- | <-- uncommitted_region.BaseAddress
* : :
* : :
* v Lower addresses v
*/
GetCurrentThreadStackLimits(&low_limit, &high_limit);
result_size = VirtualQuery((void*)low_limit,
&uncommitted_region, sizeof(uncommitted_region));
ZEND_ASSERT(result_size >= sizeof(uncommitted_region));
result_size = VirtualQuery((int8_t*)uncommitted_region.BaseAddress + uncommitted_region.RegionSize,
&guard_region, sizeof(guard_region));
ZEND_ASSERT(result_size >= sizeof(uncommitted_region));
stack->base = (void*)high_limit;
stack->max_size = (uintptr_t)high_limit - (uintptr_t)low_limit;
ZEND_ASSERT(stack->max_size > guard_region.RegionSize);
stack->max_size -= guard_region.RegionSize;
/* The uncommitted region does not shrink below 1 page */
page_size = zend_get_page_size();
ZEND_ASSERT(stack->max_size > page_size);
stack->max_size -= page_size;
return true;
}
#else /* ZEND_WIN32 */
static bool zend_call_stack_get_win32(zend_call_stack *stack)
{
return false;
}
#endif /* ZEND_WIN32 */
#if defined(__APPLE__) && defined(HAVE_PTHREAD_GET_STACKADDR_NP)
static bool zend_call_stack_get_macos(zend_call_stack *stack)
{
void *base = pthread_get_stackaddr_np(pthread_self());
size_t max_size;
if (pthread_main_np()) {
/* pthread_get_stacksize_np() returns a too low value for the main
* thread in OSX 10.9, 10.10:
* https://mail.openjdk.org/pipermail/hotspot-dev/2013-October/011353.html
* https://github.com/rust-lang/rust/issues/43347
*/
/* Stack size is 8MiB by default for main threads
* https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html */
max_size = 8 * 1024 * 1024;
} else {
max_size = pthread_get_stacksize_np(pthread_self());
}
stack->base = base;
stack->max_size = max_size;
return true;
}
#else /* defined(__APPLE__) && defined(HAVE_PTHREAD_GET_STACKADDR_NP) */
static bool zend_call_stack_get_macos(zend_call_stack *stack)
{
return false;
}
#endif /* defined(__APPLE__) && defined(HAVE_PTHREAD_GET_STACKADDR_NP) */
/** Get the stack information for the calling thread */
ZEND_API bool zend_call_stack_get(zend_call_stack *stack)
{
if (zend_call_stack_get_linux(stack)) {
return true;
}
if (zend_call_stack_get_freebsd(stack)) {
return true;
}
if (zend_call_stack_get_win32(stack)) {
return true;
}
if (zend_call_stack_get_macos(stack)) {
return true;
}
return false;
}
#endif /* ZEND_CHECK_STACK_LIMIT */

91
Zend/zend_call_stack.h Normal file
View file

@ -0,0 +1,91 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Arnaud Le Blanc <arnaud.lb@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_CALL_STACK_H
#define ZEND_CALL_STACK_H
#include "zend.h"
#include "zend_portability.h"
#ifdef __APPLE__
# include <pthread.h>
#endif
#ifdef ZEND_CHECK_STACK_LIMIT
typedef struct _zend_call_stack {
void *base;
size_t max_size;
} zend_call_stack;
ZEND_API void zend_call_stack_init(void);
ZEND_API bool zend_call_stack_get(zend_call_stack *stack);
/** Returns an approximation of the current stack position */
static zend_always_inline void *zend_call_stack_position(void) {
#ifdef ZEND_WIN32
return _AddressOfReturnAddress();
#elif HAVE_BUILTIN_FRAME_ADDRESS
return __builtin_frame_address(0);
#else
void *a;
void *pos = (void*)&a;
return pos;
#endif
}
static zend_always_inline bool zend_call_stack_overflowed(void *stack_limit) {
return (uintptr_t) zend_call_stack_position() <= (uintptr_t) stack_limit;
}
static inline void* zend_call_stack_limit(void *base, size_t size, size_t reserved_size)
{
if (UNEXPECTED(size > (uintptr_t)base)) {
return (void*)0;
}
base = (int8_t*)base - size;
if (UNEXPECTED(UINTPTR_MAX - (uintptr_t)base < reserved_size)) {
return (void*)UINTPTR_MAX;
}
return (int8_t*)base + reserved_size;
}
static inline size_t zend_call_stack_default_size(void)
{
#ifdef __linux__
return 8 * 1024 * 1024;
#endif
#ifdef __FreeBSD__
return 8 * 1024 * 1024;
#endif
#ifdef __APPLE__
// https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html
if (pthread_main_np()) {
return 8 * 1024 * 1024;
}
return 512 * 1024;
#endif
return 2 * 1024 * 1024;
}
#endif /* ZEND_CHECK_STACK_LIMIT */
#endif /* ZEND_CALL_STACK_H */

View file

@ -34,6 +34,7 @@
#include "zend_vm.h" #include "zend_vm.h"
#include "zend_enum.h" #include "zend_enum.h"
#include "zend_observer.h" #include "zend_observer.h"
#include "zend_call_stack.h"
#define SET_NODE(target, src) do { \ #define SET_NODE(target, src) do { \
target ## _type = (src)->op_type; \ target ## _type = (src)->op_type; \
@ -10425,6 +10426,14 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */
static void zend_compile_expr(znode *result, zend_ast *ast) static void zend_compile_expr(znode *result, zend_ast *ast)
{ {
#ifdef ZEND_CHECK_STACK_LIMIT
if (UNEXPECTED(zend_call_stack_overflowed(EG(stack_limit)))) {
zend_error_noreturn(E_COMPILE_ERROR,
"Maximum call stack size of %zu bytes reached during compilation. Try splitting expression",
(size_t) ((uintptr_t) EG(stack_base) - (uintptr_t) EG(stack_limit)));
}
#endif /* ZEND_CHECK_STACK_LIMIT */
uint32_t checkpoint = zend_short_circuiting_checkpoint(); uint32_t checkpoint = zend_short_circuiting_checkpoint();
zend_compile_expr_inner(result, ast); zend_compile_expr_inner(result, ast);
zend_short_circuiting_commit(checkpoint, result, ast); zend_short_circuiting_commit(checkpoint, result, ast);

View file

@ -42,6 +42,7 @@
#include "zend_smart_str.h" #include "zend_smart_str.h"
#include "zend_observer.h" #include "zend_observer.h"
#include "zend_system_id.h" #include "zend_system_id.h"
#include "zend_call_stack.h"
#include "Optimizer/zend_func_info.h" #include "Optimizer/zend_func_info.h"
/* Virtual current working directory support */ /* Virtual current working directory support */
@ -2228,6 +2229,14 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_use_new_element_for_s
zend_throw_error(NULL, "[] operator not supported for strings"); zend_throw_error(NULL, "[] operator not supported for strings");
} }
#ifdef ZEND_CHECK_STACK_LIMIT
static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_call_stack_size_error(void)
{
zend_throw_error(NULL, "Maximum call stack size of %zu bytes reached. Infinite recursion?",
(size_t) ((uintptr_t) EG(stack_base) - (uintptr_t) EG(stack_limit)));
}
#endif /* ZEND_CHECK_STACK_LIMIT */
static ZEND_COLD void zend_binary_assign_op_dim_slow(zval *container, zval *dim OPLINE_DC EXECUTE_DATA_DC) static ZEND_COLD void zend_binary_assign_op_dim_slow(zval *container, zval *dim OPLINE_DC EXECUTE_DATA_DC)
{ {
if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {

View file

@ -37,6 +37,7 @@
#include "zend_weakrefs.h" #include "zend_weakrefs.h"
#include "zend_inheritance.h" #include "zend_inheritance.h"
#include "zend_observer.h" #include "zend_observer.h"
#include "zend_call_stack.h"
#ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif #endif

View file

@ -108,6 +108,10 @@ typedef struct _zend_fiber_vm_state {
uint32_t jit_trace_num; uint32_t jit_trace_num;
JMP_BUF *bailout; JMP_BUF *bailout;
zend_fiber *active_fiber; zend_fiber *active_fiber;
#ifdef ZEND_CHECK_STACK_LIMIT
void *stack_base;
void *stack_limit;
#endif
} zend_fiber_vm_state; } zend_fiber_vm_state;
static zend_always_inline void zend_fiber_capture_vm_state(zend_fiber_vm_state *state) static zend_always_inline void zend_fiber_capture_vm_state(zend_fiber_vm_state *state)
@ -121,6 +125,10 @@ static zend_always_inline void zend_fiber_capture_vm_state(zend_fiber_vm_state *
state->jit_trace_num = EG(jit_trace_num); state->jit_trace_num = EG(jit_trace_num);
state->bailout = EG(bailout); state->bailout = EG(bailout);
state->active_fiber = EG(active_fiber); state->active_fiber = EG(active_fiber);
#ifdef ZEND_CHECK_STACK_LIMIT
state->stack_base = EG(stack_base);
state->stack_limit = EG(stack_limit);
#endif
} }
static zend_always_inline void zend_fiber_restore_vm_state(zend_fiber_vm_state *state) static zend_always_inline void zend_fiber_restore_vm_state(zend_fiber_vm_state *state)
@ -134,6 +142,10 @@ static zend_always_inline void zend_fiber_restore_vm_state(zend_fiber_vm_state *
EG(jit_trace_num) = state->jit_trace_num; EG(jit_trace_num) = state->jit_trace_num;
EG(bailout) = state->bailout; EG(bailout) = state->bailout;
EG(active_fiber) = state->active_fiber; EG(active_fiber) = state->active_fiber;
#ifdef ZEND_CHECK_STACK_LIMIT
EG(stack_base) = state->stack_base;
EG(stack_limit) = state->stack_limit;
#endif
} }
#ifdef ZEND_FIBER_UCONTEXT #ifdef ZEND_FIBER_UCONTEXT
@ -294,6 +306,31 @@ static void zend_fiber_stack_free(zend_fiber_stack *stack)
efree(stack); efree(stack);
} }
#ifdef ZEND_CHECK_STACK_LIMIT
ZEND_API void* zend_fiber_stack_limit(zend_fiber_stack *stack)
{
zend_ulong reserve = EG(reserved_stack_size);
#ifdef __APPLE__
/* On Apple Clang, the stack probing function ___chkstk_darwin incorrectly
* probes a location that is twice the entered function's stack usage away
* from the stack pointer, when using an alternative stack.
* https://openradar.appspot.com/radar?id=5497722702397440
*/
reserve = reserve * 2;
#endif
/* stack->pointer is the end of the stack */
return (int8_t*)stack->pointer + reserve;
}
ZEND_API void* zend_fiber_stack_base(zend_fiber_stack *stack)
{
return (void*)((uintptr_t)stack->pointer + stack->size);
}
#endif
#ifdef ZEND_FIBER_UCONTEXT #ifdef ZEND_FIBER_UCONTEXT
static ZEND_NORETURN void zend_fiber_trampoline(void) static ZEND_NORETURN void zend_fiber_trampoline(void)
#else #else
@ -535,6 +572,11 @@ static ZEND_STACK_ALIGNED void zend_fiber_execute(zend_fiber_transfer *transfer)
EG(jit_trace_num) = 0; EG(jit_trace_num) = 0;
EG(error_reporting) = error_reporting; EG(error_reporting) = error_reporting;
#ifdef ZEND_CHECK_STACK_LIMIT
EG(stack_base) = zend_fiber_stack_base(fiber->context.stack);
EG(stack_limit) = zend_fiber_stack_limit(fiber->context.stack);
#endif
fiber->fci.retval = &fiber->result; fiber->fci.retval = &fiber->result;
zend_call_function(&fiber->fci, &fiber->fci_cache); zend_call_function(&fiber->fci, &fiber->fci_cache);

View file

@ -136,6 +136,10 @@ struct _zend_fiber {
ZEND_API bool zend_fiber_init_context(zend_fiber_context *context, void *kind, zend_fiber_coroutine coroutine, size_t stack_size); ZEND_API bool zend_fiber_init_context(zend_fiber_context *context, void *kind, zend_fiber_coroutine coroutine, size_t stack_size);
ZEND_API void zend_fiber_destroy_context(zend_fiber_context *context); ZEND_API void zend_fiber_destroy_context(zend_fiber_context *context);
ZEND_API void zend_fiber_switch_context(zend_fiber_transfer *transfer); ZEND_API void zend_fiber_switch_context(zend_fiber_transfer *transfer);
#ifdef ZEND_CHECK_STACK_LIMIT
ZEND_API void* zend_fiber_stack_limit(zend_fiber_stack *stack);
ZEND_API void* zend_fiber_stack_base(zend_fiber_stack *stack);
#endif /* ZEND_CHECK_STACK_LIMIT */
ZEND_API void zend_fiber_switch_block(void); ZEND_API void zend_fiber_switch_block(void);
ZEND_API void zend_fiber_switch_unblock(void); ZEND_API void zend_fiber_switch_unblock(void);

View file

@ -37,6 +37,7 @@
#include "zend_multibyte.h" #include "zend_multibyte.h"
#include "zend_multiply.h" #include "zend_multiply.h"
#include "zend_arena.h" #include "zend_arena.h"
#include "zend_call_stack.h"
/* Define ZTS if you want a thread-safe Zend */ /* Define ZTS if you want a thread-safe Zend */
/*#undef ZTS*/ /*#undef ZTS*/
@ -54,6 +55,10 @@ END_EXTERN_C()
#define SYMTABLE_CACHE_SIZE 32 #define SYMTABLE_CACHE_SIZE 32
#ifdef ZEND_CHECK_STACK_LIMIT
# define ZEND_MAX_ALLOWED_STACK_SIZE_UNCHECKED -1
# define ZEND_MAX_ALLOWED_STACK_SIZE_DETECT 0
#endif
#include "zend_compile.h" #include "zend_compile.h"
@ -193,6 +198,8 @@ struct _zend_executor_globals {
zend_atomic_bool vm_interrupt; zend_atomic_bool vm_interrupt;
zend_atomic_bool timed_out; zend_atomic_bool timed_out;
zend_long hard_timeout; zend_long hard_timeout;
void *stack_base;
void *stack_limit;
#ifdef ZEND_WIN32 #ifdef ZEND_WIN32
OSVERSIONINFOEX windows_version_info; OSVERSIONINFOEX windows_version_info;
@ -271,6 +278,12 @@ struct _zend_executor_globals {
zend_string *filename_override; zend_string *filename_override;
zend_long lineno_override; zend_long lineno_override;
#ifdef ZEND_CHECK_STACK_LIMIT
zend_call_stack call_stack;
zend_long max_allowed_stack_size;
zend_ulong reserved_stack_size;
#endif
void *reserved[ZEND_MAX_RESERVED_RESOURCES]; void *reserved[ZEND_MAX_RESERVED_RESOURCES];
}; };

View file

@ -7928,6 +7928,12 @@ ZEND_VM_HELPER(zend_dispatch_try_catch_finally_helper, ANY, ANY, uint32_t try_ca
ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
{ {
const zend_op *throw_op = EG(opline_before_exception); const zend_op *throw_op = EG(opline_before_exception);
/* Exception was thrown before executing any op */
if (UNEXPECTED(!throw_op)) {
ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper, try_catch_offset, -1, 0, 0);
}
uint32_t throw_op_num = throw_op - EX(func)->op_array.opcodes; uint32_t throw_op_num = throw_op - EX(func)->op_array.opcodes;
int i, current_try_catch_offset = -1; int i, current_try_catch_offset = -1;

16
Zend/zend_vm_execute.h generated
View file

@ -3181,6 +3181,12 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_dispatch_try
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{ {
const zend_op *throw_op = EG(opline_before_exception); const zend_op *throw_op = EG(opline_before_exception);
/* Exception was thrown before executing any op */
if (UNEXPECTED(!throw_op)) {
ZEND_VM_TAIL_CALL(zend_dispatch_try_catch_finally_helper_SPEC(-1, 0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
}
uint32_t throw_op_num = throw_op - EX(func)->op_array.opcodes; uint32_t throw_op_num = throw_op - EX(func)->op_array.opcodes;
int i, current_try_catch_offset = -1; int i, current_try_catch_offset = -1;
@ -55774,6 +55780,16 @@ ZEND_API void execute_ex(zend_execute_data *ex)
LOAD_OPLINE(); LOAD_OPLINE();
ZEND_VM_LOOP_INTERRUPT_CHECK(); ZEND_VM_LOOP_INTERRUPT_CHECK();
#ifdef ZEND_CHECK_STACK_LIMIT
if (UNEXPECTED(zend_call_stack_overflowed(EG(stack_limit)))) {
zend_call_stack_size_error();
/* No opline was executed before exception */
EG(opline_before_exception) = NULL;
LOAD_OPLINE();
/* Fall through to handle exception below. */
}
#endif /* ZEND_CHECK_STACK_LIMIT */
while (1) { while (1) {
#if !defined(ZEND_VM_FP_GLOBAL_REG) || !defined(ZEND_VM_IP_GLOBAL_REG) #if !defined(ZEND_VM_FP_GLOBAL_REG) || !defined(ZEND_VM_IP_GLOBAL_REG)
int ret; int ret;

View file

@ -16,6 +16,16 @@ ZEND_API void {%EXECUTOR_NAME%}_ex(zend_execute_data *ex)
LOAD_OPLINE(); LOAD_OPLINE();
ZEND_VM_LOOP_INTERRUPT_CHECK(); ZEND_VM_LOOP_INTERRUPT_CHECK();
#ifdef ZEND_CHECK_STACK_LIMIT
if (UNEXPECTED(zend_call_stack_overflowed(EG(stack_limit)))) {
zend_call_stack_size_error();
/* No opline was executed before exception */
EG(opline_before_exception) = NULL;
LOAD_OPLINE();
/* Fall through to handle exception below. */
}
#endif /* ZEND_CHECK_STACK_LIMIT */
while (1) { while (1) {
{%ZEND_VM_CONTINUE_LABEL%} {%ZEND_VM_CONTINUE_LABEL%}
{%ZEND_VM_DISPATCH%} { {%ZEND_VM_DISPATCH%} {

View file

@ -2733,6 +2733,26 @@ AC_DEFUN([PHP_CHECK_BUILTIN_CPU_SUPPORTS], [
[$have_builtin_cpu_supports], [Whether the compiler supports __builtin_cpu_supports]) [$have_builtin_cpu_supports], [Whether the compiler supports __builtin_cpu_supports])
]) ])
dnl
dnl PHP_CHECK_BUILTIN_FRAME_ADDRESS
dnl
AC_DEFUN([PHP_CHECK_BUILTIN_FRAME_ADDRESS], [
AC_MSG_CHECKING([for __builtin_frame_address])
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [[
return __builtin_frame_address(0) != (void*)0;
]])], [
have_builtin_frame_address=1
AC_MSG_RESULT([yes])
], [
have_builtin_frame_address=0
AC_MSG_RESULT([no])
])
AC_DEFINE_UNQUOTED([PHP_HAVE_BUILTIN_FRAME_ADDRESS],
[$have_builtin_frame_address], [Whether the compiler supports __builtin_frame_address])
])
dnl dnl
dnl PHP_PATCH_CONFIG_HEADERS([FILE]) dnl PHP_PATCH_CONFIG_HEADERS([FILE])
dnl dnl

View file

@ -510,6 +510,8 @@ dnl Check __builtin_cpu_init
PHP_CHECK_BUILTIN_CPU_INIT PHP_CHECK_BUILTIN_CPU_INIT
dnl Check __builtin_cpu_supports dnl Check __builtin_cpu_supports
PHP_CHECK_BUILTIN_CPU_SUPPORTS PHP_CHECK_BUILTIN_CPU_SUPPORTS
dnl Check __builtin_frame_address
PHP_CHECK_BUILTIN_FRAME_ADDRESS
dnl Check prctl dnl Check prctl
PHP_CHECK_PRCTL PHP_CHECK_PRCTL
dnl Check procctl dnl Check procctl
@ -1701,7 +1703,7 @@ PHP_ADD_SOURCES_X(/main, internal_functions_cli.c, -DZEND_ENABLE_STATIC_TSRMLS_C
PHP_ADD_SOURCES(Zend, \ PHP_ADD_SOURCES(Zend, \
zend_language_parser.c zend_language_scanner.c \ zend_language_parser.c zend_language_scanner.c \
zend_ini_parser.c zend_ini_scanner.c \ zend_ini_parser.c zend_ini_scanner.c \
zend_alloc.c zend_compile.c zend_constants.c zend_dtrace.c \ zend_alloc.c zend_call_stack.c zend_compile.c zend_constants.c zend_dtrace.c \
zend_execute_API.c zend_highlight.c zend_llist.c \ zend_execute_API.c zend_highlight.c zend_llist.c \
zend_vm_opcodes.c zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \ zend_vm_opcodes.c zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \

View file

@ -21,7 +21,7 @@
static ZEND_COLD void undef_result_after_exception(void) { static ZEND_COLD void undef_result_after_exception(void) {
const zend_op *opline = EG(opline_before_exception); const zend_op *opline = EG(opline_before_exception);
ZEND_ASSERT(EG(exception)); ZEND_ASSERT(EG(exception));
if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { if (opline && opline->result_type & (IS_VAR | IS_TMP_VAR)) {
zend_execute_data *execute_data = EG(current_execute_data); zend_execute_data *execute_data = EG(current_execute_data);
ZVAL_UNDEF(EX_VAR(opline->result.var)); ZVAL_UNDEF(EX_VAR(opline->result.var));
} }
@ -785,7 +785,7 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_rw_helper(zend_array *ht, zval *di
if (UNEXPECTED(opline->opcode == ZEND_HANDLE_EXCEPTION)) { if (UNEXPECTED(opline->opcode == ZEND_HANDLE_EXCEPTION)) {
opline = EG(opline_before_exception); opline = EG(opline_before_exception);
} }
if (!zend_jit_undefined_op_helper_write(ht, opline->op2.var)) { if (opline && !zend_jit_undefined_op_helper_write(ht, opline->op2.var)) {
if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { if (opline->result_type & (IS_VAR | IS_TMP_VAR)) {
if (EG(exception)) { if (EG(exception)) {
ZVAL_UNDEF(EX_VAR(opline->result.var)); ZVAL_UNDEF(EX_VAR(opline->result.var));
@ -1003,7 +1003,8 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_w_helper(zend_array *ht, zval *dim
default: default:
zend_jit_illegal_offset(); zend_jit_illegal_offset();
undef_result_after_exception(); undef_result_after_exception();
if ((EG(opline_before_exception)+1)->opcode == ZEND_OP_DATA if (EG(opline_before_exception)
&& (EG(opline_before_exception)+1)->opcode == ZEND_OP_DATA
&& ((EG(opline_before_exception)+1)->op1_type & (IS_VAR|IS_TMP_VAR))) { && ((EG(opline_before_exception)+1)->op1_type & (IS_VAR|IS_TMP_VAR))) {
zend_execute_data *execute_data = EG(current_execute_data); zend_execute_data *execute_data = EG(current_execute_data);

View file

@ -183,7 +183,7 @@ bool ZEND_FASTCALL zend_jit_deprecated_helper(OPLINE_D)
zend_execute_data *execute_data = EG(current_execute_data); zend_execute_data *execute_data = EG(current_execute_data);
#endif #endif
const zend_op *opline = EG(opline_before_exception); const zend_op *opline = EG(opline_before_exception);
if (RETURN_VALUE_USED(opline)) { if (opline && RETURN_VALUE_USED(opline)) {
ZVAL_UNDEF(EX_VAR(opline->result.var)); ZVAL_UNDEF(EX_VAR(opline->result.var));
} }

View file

@ -95,6 +95,10 @@ static ZEND_STACK_ALIGNED void zend_test_fiber_execute(zend_fiber_transfer *tran
EG(current_execute_data) = execute_data; EG(current_execute_data) = execute_data;
EG(jit_trace_num) = 0; EG(jit_trace_num) = 0;
#ifdef ZEND_CHECK_STACK_LIMIT
EG(stack_base) = zend_fiber_stack_base(fiber->context.stack);
EG(stack_limit) = zend_fiber_stack_limit(fiber->context.stack);
#endif
fiber->fci.retval = &retval; fiber->fci.retval = &retval;
zend_call_function(&fiber->fci, &fiber->fci_cache); zend_call_function(&fiber->fci, &fiber->fci_cache);

View file

@ -30,6 +30,7 @@
#include "zend_weakrefs.h" #include "zend_weakrefs.h"
#include "Zend/Optimizer/zend_optimizer.h" #include "Zend/Optimizer/zend_optimizer.h"
#include "test_arginfo.h" #include "test_arginfo.h"
#include "zend_call_stack.h"
ZEND_DECLARE_MODULE_GLOBALS(zend_test) ZEND_DECLARE_MODULE_GLOBALS(zend_test)
@ -456,6 +457,65 @@ static ZEND_FUNCTION(zend_test_parameter_with_attribute)
RETURN_LONG(1); RETURN_LONG(1);
} }
#ifdef ZEND_CHECK_STACK_LIMIT
static ZEND_FUNCTION(zend_test_zend_call_stack_get)
{
zend_call_stack stack;
ZEND_PARSE_PARAMETERS_NONE();
if (zend_call_stack_get(&stack)) {
zend_string *str;
array_init(return_value);
str = strpprintf(0, "%p", stack.base);
add_assoc_str(return_value, "base", str);
str = strpprintf(0, "0x%zx", stack.max_size);
add_assoc_str(return_value, "max_size", str);
str = strpprintf(0, "%p", zend_call_stack_position());
add_assoc_str(return_value, "position", str);
str = strpprintf(0, "%p", EG(stack_limit));
add_assoc_str(return_value, "EG(stack_limit)", str);
return;
}
RETURN_NULL();
}
zend_long (*volatile zend_call_stack_use_all_fun)(void *limit);
static zend_long zend_call_stack_use_all(void *limit)
{
if (zend_call_stack_overflowed(limit)) {
return 1;
}
return 1 + zend_call_stack_use_all_fun(limit);
}
static ZEND_FUNCTION(zend_test_zend_call_stack_use_all)
{
zend_call_stack stack;
ZEND_PARSE_PARAMETERS_NONE();
if (!zend_call_stack_get(&stack)) {
return;
}
zend_call_stack_use_all_fun = zend_call_stack_use_all;
void *limit = zend_call_stack_limit(stack.base, stack.max_size, 4096);
RETURN_LONG(zend_call_stack_use_all(limit));
}
#endif /* ZEND_CHECK_STACK_LIMIT */
static zend_object *zend_test_class_new(zend_class_entry *class_type) static zend_object *zend_test_class_new(zend_class_entry *class_type)
{ {
zend_object *obj = zend_objects_new(class_type); zend_object *obj = zend_objects_new(class_type);

View file

@ -161,6 +161,11 @@ namespace {
function zend_test_zend_ini_parse_uquantity(string $str): int {} function zend_test_zend_ini_parse_uquantity(string $str): int {}
function zend_test_zend_ini_str(): string {} function zend_test_zend_ini_str(): string {}
#ifdef ZEND_CHECK_STACK_LIMIT
function zend_test_zend_call_stack_get(): ?array {}
function zend_test_zend_call_stack_use_all(): int {}
#endif
} }
namespace ZendTestNS { namespace ZendTestNS {

View file

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead. /* This is a generated file, edit the .stub.php file instead.
* Stub hash: 786b35a1fbff38215431d5ae46a5816c70defce5 */ * Stub hash: 5c7af89178bc4ea0f49fbf516d81f4fdaebece22 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
@ -97,6 +97,16 @@ ZEND_END_ARG_INFO()
#define arginfo_zend_test_zend_ini_str arginfo_zend_get_current_func_name #define arginfo_zend_test_zend_ini_str arginfo_zend_get_current_func_name
#if defined(ZEND_CHECK_STACK_LIMIT)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_zend_call_stack_get, 0, 0, IS_ARRAY, 1)
ZEND_END_ARG_INFO()
#endif
#if defined(ZEND_CHECK_STACK_LIMIT)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_zend_call_stack_use_all, 0, 0, IS_LONG, 0)
ZEND_END_ARG_INFO()
#endif
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ZendTestNS2_namespaced_func, 0, 0, _IS_BOOL, 0) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ZendTestNS2_namespaced_func, 0, 0, _IS_BOOL, 0)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
@ -185,6 +195,12 @@ static ZEND_FUNCTION(zend_call_method);
static ZEND_FUNCTION(zend_test_zend_ini_parse_quantity); static ZEND_FUNCTION(zend_test_zend_ini_parse_quantity);
static ZEND_FUNCTION(zend_test_zend_ini_parse_uquantity); static ZEND_FUNCTION(zend_test_zend_ini_parse_uquantity);
static ZEND_FUNCTION(zend_test_zend_ini_str); static ZEND_FUNCTION(zend_test_zend_ini_str);
#if defined(ZEND_CHECK_STACK_LIMIT)
static ZEND_FUNCTION(zend_test_zend_call_stack_get);
#endif
#if defined(ZEND_CHECK_STACK_LIMIT)
static ZEND_FUNCTION(zend_test_zend_call_stack_use_all);
#endif
static ZEND_FUNCTION(ZendTestNS2_namespaced_func); static ZEND_FUNCTION(ZendTestNS2_namespaced_func);
static ZEND_FUNCTION(ZendTestNS2_namespaced_deprecated_func); static ZEND_FUNCTION(ZendTestNS2_namespaced_deprecated_func);
static ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_func); static ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_func);
@ -235,6 +251,12 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(zend_test_zend_ini_parse_quantity, arginfo_zend_test_zend_ini_parse_quantity) ZEND_FE(zend_test_zend_ini_parse_quantity, arginfo_zend_test_zend_ini_parse_quantity)
ZEND_FE(zend_test_zend_ini_parse_uquantity, arginfo_zend_test_zend_ini_parse_uquantity) ZEND_FE(zend_test_zend_ini_parse_uquantity, arginfo_zend_test_zend_ini_parse_uquantity)
ZEND_FE(zend_test_zend_ini_str, arginfo_zend_test_zend_ini_str) ZEND_FE(zend_test_zend_ini_str, arginfo_zend_test_zend_ini_str)
#if defined(ZEND_CHECK_STACK_LIMIT)
ZEND_FE(zend_test_zend_call_stack_get, arginfo_zend_test_zend_call_stack_get)
#endif
#if defined(ZEND_CHECK_STACK_LIMIT)
ZEND_FE(zend_test_zend_call_stack_use_all, arginfo_zend_test_zend_call_stack_use_all)
#endif
ZEND_NS_FALIAS("ZendTestNS2", namespaced_func, ZendTestNS2_namespaced_func, arginfo_ZendTestNS2_namespaced_func) ZEND_NS_FALIAS("ZendTestNS2", namespaced_func, ZendTestNS2_namespaced_func, arginfo_ZendTestNS2_namespaced_func)
ZEND_NS_DEP_FALIAS("ZendTestNS2", namespaced_deprecated_func, ZendTestNS2_namespaced_deprecated_func, arginfo_ZendTestNS2_namespaced_deprecated_func) ZEND_NS_DEP_FALIAS("ZendTestNS2", namespaced_deprecated_func, ZendTestNS2_namespaced_deprecated_func, arginfo_ZendTestNS2_namespaced_deprecated_func)
ZEND_NS_FALIAS("ZendTestNS2", namespaced_aliased_func, zend_test_void_return, arginfo_ZendTestNS2_namespaced_aliased_func) ZEND_NS_FALIAS("ZendTestNS2", namespaced_aliased_func, zend_test_void_return, arginfo_ZendTestNS2_namespaced_aliased_func)

View file

@ -611,7 +611,7 @@ PHPDBG_API bool phpdbg_check_caught_ex(zend_execute_data *execute_data, zend_obj
uint32_t op_num, i; uint32_t op_num, i;
zend_op_array *op_array = &execute_data->func->op_array; zend_op_array *op_array = &execute_data->func->op_array;
if (execute_data->opline >= EG(exception_op) && execute_data->opline < EG(exception_op) + 3) { if (execute_data->opline >= EG(exception_op) && execute_data->opline < EG(exception_op) + 3 && EG(opline_before_exception)) {
op = EG(opline_before_exception); op = EG(opline_before_exception);
} else { } else {
op = execute_data->opline; op = execute_data->opline;

View file

@ -228,8 +228,8 @@ STDOUT.WriteLine("Build dir: " + get_define('BUILD_DIR'));
STDOUT.WriteLine("PHP Core: " + get_define('PHPDLL') + " and " + get_define('PHPLIB')); STDOUT.WriteLine("PHP Core: " + get_define('PHPDLL') + " and " + get_define('PHPLIB'));
ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \
zend_ini_parser.c zend_ini_scanner.c zend_alloc.c zend_compile.c \ zend_ini_parser.c zend_ini_scanner.c zend_alloc.c zend_call_stack.c \
zend_constants.c zend_exceptions.c \ zend_compile.c zend_constants.c zend_exceptions.c \
zend_execute_API.c zend_highlight.c \ zend_execute_API.c zend_highlight.c \
zend_llist.c zend_vm_opcodes.c zend_opcode.c zend_operators.c zend_ptr_stack.c \ zend_llist.c zend_vm_opcodes.c zend_opcode.c zend_operators.c zend_ptr_stack.c \
zend_stack.c zend_variables.c zend.c zend_API.c zend_extensions.c \ zend_stack.c zend_variables.c zend.c zend_API.c zend_extensions.c \
@ -303,6 +303,9 @@ if (VS_TOOLSET && VCVERS >= 1914) {
AC_DEFINE('HAVE_STRNLEN', 1); AC_DEFINE('HAVE_STRNLEN', 1);
AC_DEFINE('ZEND_STACK_GROWS_DOWNWARDS', 1)
AC_DEFINE('ZEND_CHECK_STACK_LIMIT', 1)
ADD_SOURCES("main/streams", "streams.c cast.c memory.c filter.c plain_wrapper.c \ ADD_SOURCES("main/streams", "streams.c cast.c memory.c filter.c plain_wrapper.c \
userspace.c transports.c xp_socket.c mmap.c glob_wrapper.c"); userspace.c transports.c xp_socket.c mmap.c glob_wrapper.c");
ADD_FLAG("CFLAGS_BD_MAIN_STREAMS", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); ADD_FLAG("CFLAGS_BD_MAIN_STREAMS", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1");

View file

@ -5,7 +5,7 @@
/* Define the minimum supported version */ /* Define the minimum supported version */
#undef _WIN32_WINNT #undef _WIN32_WINNT
#undef NTDDI_VERSION #undef NTDDI_VERSION
#define _WIN32_WINNT 0x0601 #define _WIN32_WINNT 0x0602
#define NTDDI_VERSION 0x06010000 #define NTDDI_VERSION 0x06010000
/* Default PHP / PEAR directories */ /* Default PHP / PEAR directories */