From: Felipe Pena Date: Tue, 3 Jun 2008 14:07:15 +0000 (+0000) Subject: - MFH: Fixed bug #44769 (declaring private magic methods should throw error) X-Git-Tag: BEFORE_NEW_PARAMETER_PARSE~85 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=402fb5285d43d94597515847d6dbe822d2eb3130;p=php - MFH: Fixed bug #44769 (declaring private magic methods should throw error) --- 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-- +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-- + +--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-- + +--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-- + +--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-- + +--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-- + +--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-- + +--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-- + +--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-- + +--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-- + +--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; diff --git a/tests/classes/__call_005.phpt b/tests/classes/__call_005.phpt index c82a853f72..5706a7c004 100644 --- a/tests/classes/__call_005.phpt +++ b/tests/classes/__call_005.phpt @@ -22,15 +22,4 @@ $b = new B(); $b->test(); ?> --EXPECTF-- -In A::__call(test1, array(1,a)) -object(B)#1 (0) { -} -In A::__call(test2, array(1,a)) -object(B)#1 (0) { -} -In A::__call(test3, array(1,a)) -object(B)#1 (0) { -} -In A::__call(test4, array(1,a)) -object(B)#1 (0) { -} \ No newline at end of file +Fatal error: The magic method __call() must have public visibility and can not be static in %s on line %d