diff options
author | Felipe Pena <felipe@php.net> | 2008-06-03 14:07:15 +0000 |
---|---|---|
committer | Felipe Pena <felipe@php.net> | 2008-06-03 14:07:15 +0000 |
commit | 402fb5285d43d94597515847d6dbe822d2eb3130 (patch) | |
tree | b10596a677400f9e7e5d45b5e59854665e93a18d /Zend | |
parent | fe0ef8b17c8d3c3671838e41322038f97d90c62b (diff) | |
download | php-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.phpt | 49 | ||||
-rw-r--r-- | Zend/tests/magic_methods_002.phpt | 14 | ||||
-rw-r--r-- | Zend/tests/magic_methods_003.phpt | 14 | ||||
-rw-r--r-- | Zend/tests/magic_methods_004.phpt | 14 | ||||
-rw-r--r-- | Zend/tests/magic_methods_005.phpt | 12 | ||||
-rw-r--r-- | Zend/tests/magic_methods_006.phpt | 12 | ||||
-rw-r--r-- | Zend/tests/magic_methods_007.phpt | 12 | ||||
-rw-r--r-- | Zend/tests/magic_methods_008.phpt | 17 | ||||
-rw-r--r-- | Zend/tests/magic_methods_009.phpt | 13 | ||||
-rw-r--r-- | Zend/tests/magic_methods_010.phpt | 13 | ||||
-rw-r--r-- | Zend/zend_compile.c | 53 |
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; |