Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test #3

Closed
wants to merge 15 commits into from
Closed
1 change: 1 addition & 0 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ environment:
#PDO_MYSQL_TEST_PASS: 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!"
STACK_LIMIT_DEFAULTS_CHECK: 1
#build permutations
matrix:
- THREAD_SAFE: 0
Expand Down
1 change: 1 addition & 0 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -201,4 +201,5 @@ freebsd_task:
tests_script:
- export SKIP_IO_CAPTURE_TESTS=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
5 changes: 4 additions & 1 deletion .github/actions/test-linux/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,17 @@ runs:
export PDO_OCI_TEST_DSN="oci:dbname=localhost/XEPDB1;charset=AL32UTF8"
export SKIP_IO_CAPTURE_TESTS=1
export TEST_PHP_JUNIT=junit.out.xml
export STACK_LIMIT_DEFAULTS_CHECK=1
sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \
-j$(/usr/bin/nproc) \
-g FAIL,BORK,LEAK,XLEAK \
--no-progress \
--offline \
--show-diff \
--show-out \
--show-slow 1000 \
--set-timeout 120
--set-timeout 120 \
Zend/tests/stack_limit
- uses: actions/upload-artifact@v3
if: always() && inputs.testArtifacts != null
with:
Expand Down
1 change: 1 addition & 0 deletions .github/actions/test-macos/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ runs:
export SKIP_IO_CAPTURE_TESTS=1
export CI_NO_IPV6=1
export TEST_PHP_JUNIT=junit.out.xml
export STACK_LIMIT_DEFAULTS_CHECK=1
sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \
-j$(sysctl -n hw.ncpu) \
-g FAIL,BORK,LEAK,XLEAK \
Expand Down
32 changes: 31 additions & 1 deletion Zend/Zend.m4
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,37 @@ _LT_AC_TRY_DLOPEN_SELF([
])

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
])
Expand Down
77 changes: 77 additions & 0 deletions Zend/tests/stack_limit/stack_limit_001.phpt
Original file line number Diff line number Diff line change
@@ -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?
80 changes: 80 additions & 0 deletions Zend/tests/stack_limit/stack_limit_002.phpt
Original file line number Diff line number Diff line change
@@ -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?
62 changes: 62 additions & 0 deletions Zend/tests/stack_limit/stack_limit_003.phpt
Original file line number Diff line number Diff line change
@@ -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?
50 changes: 50 additions & 0 deletions Zend/tests/stack_limit/stack_limit_004.phpt
Original file line number Diff line number Diff line change
@@ -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)
Loading