summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2021-02-22 10:33:16 +0100
committerNikita Popov <nikita.ppv@gmail.com>2021-02-22 10:33:16 +0100
commit8e8e0017b986d4a2ca45cb2931e4d50f565e1f89 (patch)
tree3e60109021841ee9506e3ab00062f8f077250efb /Zend
parentb3f4a3105c7a577baacd25ac7b76a32aa96cd7ca (diff)
parentab989441957956522c1663f1a0662067afbfdb6c (diff)
downloadphp-git-8e8e0017b986d4a2ca45cb2931e4d50f565e1f89.tar.gz
Merge branch 'PHP-8.0'
* PHP-8.0: Fix trampoline leak on dynamic static call of non-static method
Diffstat (limited to 'Zend')
-rw-r--r--Zend/tests/dynamic_call_non_static.phpt30
-rw-r--r--Zend/zend_execute.c8
2 files changed, 38 insertions, 0 deletions
diff --git a/Zend/tests/dynamic_call_non_static.phpt b/Zend/tests/dynamic_call_non_static.phpt
new file mode 100644
index 0000000000..f73d29a131
--- /dev/null
+++ b/Zend/tests/dynamic_call_non_static.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Dynamic static call of non-static method
+--FILE--
+<?php
+class Foo {
+ function test1() {
+ $method = ['Foo', 'bar'];
+ $method();
+ }
+ function test2() {
+ $method = 'Foo::bar';
+ $method();
+ }
+ function __call($name, $args) {}
+}
+$x = new Foo;
+try {
+ $x->test1();
+} catch (Error $e) {
+ echo $e->getMessage(), "\n";
+}
+try {
+ $x->test2();
+} catch (Error $e) {
+ echo $e->getMessage(), "\n";
+}
+?>
+--EXPECT--
+Non-static method Foo::bar() cannot be called statically
+Non-static method Foo::bar() cannot be called statically
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 9878bf43b2..8245f47605 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -4021,6 +4021,10 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_string(zend_s
if (UNEXPECTED(!(fbc->common.fn_flags & ZEND_ACC_STATIC))) {
zend_non_static_method_call(fbc);
+ if (fbc->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+ zend_string_release_ex(fbc->common.function_name, 0);
+ zend_free_trampoline(fbc);
+ }
return NULL;
}
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
@@ -4145,6 +4149,10 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_ar
}
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
zend_non_static_method_call(fbc);
+ if (fbc->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+ zend_string_release_ex(fbc->common.function_name, 0);
+ zend_free_trampoline(fbc);
+ }
return NULL;
}
object_or_called_scope = called_scope;