summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorFelipe Pena <felipe@php.net>2008-06-03 14:07:15 +0000
committerFelipe Pena <felipe@php.net>2008-06-03 14:07:15 +0000
commit402fb5285d43d94597515847d6dbe822d2eb3130 (patch)
treeb10596a677400f9e7e5d45b5e59854665e93a18d /Zend
parentfe0ef8b17c8d3c3671838e41322038f97d90c62b (diff)
downloadphp-git-402fb5285d43d94597515847d6dbe822d2eb3130.tar.gz
- MFH: Fixed bug #44769 (declaring private magic methods should throw error)
Diffstat (limited to 'Zend')
-rw-r--r--Zend/tests/magic_methods_001.phpt49
-rw-r--r--Zend/tests/magic_methods_002.phpt14
-rw-r--r--Zend/tests/magic_methods_003.phpt14
-rw-r--r--Zend/tests/magic_methods_004.phpt14
-rw-r--r--Zend/tests/magic_methods_005.phpt12
-rw-r--r--Zend/tests/magic_methods_006.phpt12
-rw-r--r--Zend/tests/magic_methods_007.phpt12
-rw-r--r--Zend/tests/magic_methods_008.phpt17
-rw-r--r--Zend/tests/magic_methods_009.phpt13
-rw-r--r--Zend/tests/magic_methods_010.phpt13
-rw-r--r--Zend/zend_compile.c53
11 files changed, 222 insertions, 1 deletions
diff --git a/Zend/tests/magic_methods_001.phpt b/Zend/tests/magic_methods_001.phpt
new file mode 100644
index 0000000000..45701bf0a4
--- /dev/null
+++ b/Zend/tests/magic_methods_001.phpt
@@ -0,0 +1,49 @@
+--TEST--
+Testing several magic methods
+--FILE--
+<?php
+
+class foo {
+ function __unset($a) {
+ print "unset\n";
+ var_dump($a);
+ }
+
+ public function __call($a, $b) {
+ print "call\n";
+ var_dump($a);
+ }
+ function __clone() {
+ print "clone\n";
+ }
+ static public function __callstatic($a, $b) {
+ print "callstatic\n";
+ }
+
+ public function __tostring() {
+ return 'foo';
+ }
+}
+
+
+$a = new foo;
+
+$a->sdfdsa();
+
+$a::test();
+
+clone $a;
+
+var_dump((string)$a);
+
+unset($a->a);
+
+?>
+--EXPECT--
+call
+string(6) "sdfdsa"
+callstatic
+clone
+string(3) "foo"
+unset
+string(1) "a"
diff --git a/Zend/tests/magic_methods_002.phpt b/Zend/tests/magic_methods_002.phpt
new file mode 100644
index 0000000000..da29aaa3a0
--- /dev/null
+++ b/Zend/tests/magic_methods_002.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Testing __unset with private visibility
+--FILE--
+<?php
+
+class foo {
+ private function __unset($a) {
+ print "unset\n";
+ }
+}
+
+?>
+--EXPECTF--
+Fatal error: The magic method __unset() must have public visibility and can not be static in %s on line %d
diff --git a/Zend/tests/magic_methods_003.phpt b/Zend/tests/magic_methods_003.phpt
new file mode 100644
index 0000000000..25802223c4
--- /dev/null
+++ b/Zend/tests/magic_methods_003.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Testing __unset declaring as static
+--FILE--
+<?php
+
+class foo {
+ static function __unset($a) {
+ print "unset\n";
+ }
+}
+
+?>
+--EXPECTF--
+Fatal error: The magic method __unset() must have public visibility and can not be static in %s on line %d
diff --git a/Zend/tests/magic_methods_004.phpt b/Zend/tests/magic_methods_004.phpt
new file mode 100644
index 0000000000..c75e454395
--- /dev/null
+++ b/Zend/tests/magic_methods_004.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Testing __unset() with protected visibility
+--FILE--
+<?php
+
+class foo {
+ protected function __unset($a) {
+ print "unset\n";
+ }
+}
+
+?>
+--EXPECTF--
+Fatal error: The magic method __unset() must have public visibility and can not be static in %s on line %d
diff --git a/Zend/tests/magic_methods_005.phpt b/Zend/tests/magic_methods_005.phpt
new file mode 100644
index 0000000000..2cf84dc997
--- /dev/null
+++ b/Zend/tests/magic_methods_005.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Testing __call() declaration in interface with wrong modifier
+--FILE--
+<?php
+
+interface a {
+ static function __call($a, $b);
+}
+
+?>
+--EXPECTF--
+Fatal error: The magic method __call() must have public visibility and can not be static in %s on line %d
diff --git a/Zend/tests/magic_methods_006.phpt b/Zend/tests/magic_methods_006.phpt
new file mode 100644
index 0000000000..3fdab062b0
--- /dev/null
+++ b/Zend/tests/magic_methods_006.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Testing __callstatic declaration in interface with missing the 'static' modifier
+--FILE--
+<?php
+
+interface a {
+ function __callstatic($a, $b);
+}
+
+?>
+--EXPECTF--
+Fatal error: The magic method __callStatic() must have public visibility and be static in %s on line %d
diff --git a/Zend/tests/magic_methods_007.phpt b/Zend/tests/magic_methods_007.phpt
new file mode 100644
index 0000000000..0f3b9e521d
--- /dev/null
+++ b/Zend/tests/magic_methods_007.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Testing __set() declaration in abstract class with wrong modifier
+--FILE--
+<?php
+
+abstract class b {
+ abstract protected function __set($a);
+}
+
+?>
+--EXPECTF--
+Fatal error: The magic method __set() must have public visibility and can not be static in %s on line %d
diff --git a/Zend/tests/magic_methods_008.phpt b/Zend/tests/magic_methods_008.phpt
new file mode 100644
index 0000000000..b3f7362493
--- /dev/null
+++ b/Zend/tests/magic_methods_008.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Testing __set implementation with wrong declaration
+--FILE--
+<?php
+
+abstract class b {
+ abstract function __set($a, $b);
+}
+
+class a extends b {
+ private function __set($a, $b) {
+ }
+}
+
+?>
+--EXPECTF--
+Fatal error: The magic method __set() must have public visibility and can not be static in %s on line %d
diff --git a/Zend/tests/magic_methods_009.phpt b/Zend/tests/magic_methods_009.phpt
new file mode 100644
index 0000000000..aac3d4c6ca
--- /dev/null
+++ b/Zend/tests/magic_methods_009.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Testing __callstatic declaration with wrong modifier
+--FILE--
+<?php
+
+class a {
+ static protected function __callstatic($a, $b) {
+ }
+}
+
+?>
+--EXPECTF--
+Fatal error: The magic method __callStatic() must have public visibility and be static in %s on line %d
diff --git a/Zend/tests/magic_methods_010.phpt b/Zend/tests/magic_methods_010.phpt
new file mode 100644
index 0000000000..33e6b873ff
--- /dev/null
+++ b/Zend/tests/magic_methods_010.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Testing __toString() declaration with wrong modifier
+--FILE--
+<?php
+
+class a {
+ static protected function __toString($a, $b) {
+ }
+}
+
+?>
+--EXPECTF--
+Fatal error: The magic method __toString() must have public visibility and can not be static in %s on line %d
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 19fc541a05..476e2d04e7 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -1203,7 +1203,37 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
fn_flags |= ZEND_ACC_PUBLIC;
}
- if (!(CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE)) {
+ if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) {
+ if ((name_len == sizeof(ZEND_CALL_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)-1))) {
+ if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
+ zend_error(E_COMPILE_ERROR, "The magic method __call() must have public visibility and can not be static");
+ }
+ } else if ((name_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1))) {
+ if ((fn_flags & (ZEND_ACC_PPP_MASK ^ ZEND_ACC_PUBLIC)) || (fn_flags & ZEND_ACC_STATIC) == 0) {
+ zend_error(E_COMPILE_ERROR, "The magic method __callStatic() must have public visibility and be static");
+ }
+ } else if ((name_len == sizeof(ZEND_GET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME)-1))) {
+ if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
+ zend_error(E_COMPILE_ERROR, "The magic method __get() must have public visibility and can not be static");
+ }
+ } else if ((name_len == sizeof(ZEND_SET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME)-1))) {
+ if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
+ zend_error(E_COMPILE_ERROR, "The magic method __set() must have public visibility and can not be static");
+ }
+ } else if ((name_len == sizeof(ZEND_UNSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME)-1))) {
+ if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
+ zend_error(E_COMPILE_ERROR, "The magic method __unset() must have public visibility and can not be static");
+ }
+ } else if ((name_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME)-1))) {
+ if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
+ zend_error(E_COMPILE_ERROR, "The magic method __isset() must have public visibility and can not be static");
+ }
+ } else if ((name_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1))) {
+ if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
+ zend_error(E_COMPILE_ERROR, "The magic method __toString() must have public visibility and can not be static");
+ }
+ }
+ } else {
char *short_class_name;
int short_class_name_length;
char *short_class_lcname;
@@ -1235,18 +1265,39 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
} else if ((name_len == sizeof(ZEND_CLONE_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME)-1))) {
CG(active_class_entry)->clone = (zend_function *) CG(active_op_array);
} else if ((name_len == sizeof(ZEND_CALL_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)-1))) {
+ if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
+ zend_error(E_COMPILE_ERROR, "The magic method __call() must have public visibility and can not be static");
+ }
CG(active_class_entry)->__call = (zend_function *) CG(active_op_array);
} else if ((name_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1))) {
+ if ((fn_flags & (ZEND_ACC_PPP_MASK ^ ZEND_ACC_PUBLIC)) || (fn_flags & ZEND_ACC_STATIC) == 0) {
+ zend_error(E_COMPILE_ERROR, "The magic method __callStatic() must have public visibility and be static");
+ }
CG(active_class_entry)->__callstatic = (zend_function *) CG(active_op_array);
} else if ((name_len == sizeof(ZEND_GET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME)-1))) {
+ if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
+ zend_error(E_COMPILE_ERROR, "The magic method __get() must have public visibility and can not be static");
+ }
CG(active_class_entry)->__get = (zend_function *) CG(active_op_array);
} else if ((name_len == sizeof(ZEND_SET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME)-1))) {
+ if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
+ zend_error(E_COMPILE_ERROR, "The magic method __set() must have public visibility and can not be static");
+ }
CG(active_class_entry)->__set = (zend_function *) CG(active_op_array);
} else if ((name_len == sizeof(ZEND_UNSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME)-1))) {
+ if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
+ zend_error(E_COMPILE_ERROR, "The magic method __unset() must have public visibility and can not be static");
+ }
CG(active_class_entry)->__unset = (zend_function *) CG(active_op_array);
} else if ((name_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME)-1))) {
+ if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
+ zend_error(E_COMPILE_ERROR, "The magic method __isset() must have public visibility and can not be static");
+ }
CG(active_class_entry)->__isset = (zend_function *) CG(active_op_array);
} else if ((name_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1))) {
+ if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
+ zend_error(E_COMPILE_ERROR, "The magic method __toString() must have public visibility and can not be static");
+ }
CG(active_class_entry)->__tostring = (zend_function *) CG(active_op_array);
} else if (!(fn_flags & ZEND_ACC_STATIC)) {
CG(active_op_array)->fn_flags |= ZEND_ACC_ALLOW_STATIC;