From: Antony Dovgal Date: Fri, 31 Aug 2007 12:36:00 +0000 (+0000) Subject: prohibit arguments by ref in magic methods X-Git-Tag: RELEASE_2_0_0a1~1903 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e8a72ac5e19dced4cf839af4f1176315322ad731;p=php prohibit arguments by ref in magic methods --- diff --git a/Zend/tests/magic_by_ref_001.phpt b/Zend/tests/magic_by_ref_001.phpt new file mode 100644 index 0000000000..e9bcf8fa28 --- /dev/null +++ b/Zend/tests/magic_by_ref_001.phpt @@ -0,0 +1,17 @@ +--TEST-- +passing first parameter of __set() by ref +--FILE-- +$name = 1; + +echo "Done\n"; +?> +--EXPECTF-- +Fatal error: Method test::__set() cannot take arguments by reference in %s on line %d diff --git a/Zend/tests/magic_by_ref_002.phpt b/Zend/tests/magic_by_ref_002.phpt new file mode 100644 index 0000000000..cb62f67f56 --- /dev/null +++ b/Zend/tests/magic_by_ref_002.phpt @@ -0,0 +1,16 @@ +--TEST-- +passing second parameter of __set() by ref +--FILE-- +prop = 1; + +echo "Done\n"; +?> +--EXPECTF-- +Fatal error: Method test::__set() cannot take arguments by reference in %s on line %d diff --git a/Zend/tests/magic_by_ref_003.phpt b/Zend/tests/magic_by_ref_003.phpt new file mode 100644 index 0000000000..022cbd563c --- /dev/null +++ b/Zend/tests/magic_by_ref_003.phpt @@ -0,0 +1,17 @@ +--TEST-- +passing parameter of __get() by ref +--FILE-- +$name); + +echo "Done\n"; +?> +--EXPECTF-- +Fatal error: Method test::__get() cannot take arguments by reference in %s on line %d diff --git a/Zend/tests/magic_by_ref_004.phpt b/Zend/tests/magic_by_ref_004.phpt new file mode 100644 index 0000000000..aa04d1aee6 --- /dev/null +++ b/Zend/tests/magic_by_ref_004.phpt @@ -0,0 +1,18 @@ +--TEST-- +passing parameter of __unset() by ref +--FILE-- +$name); + +echo "Done\n"; +?> +--EXPECTF-- +Fatal error: Method test::__unset() cannot take arguments by reference in %s on line %d diff --git a/Zend/tests/magic_by_ref_005.phpt b/Zend/tests/magic_by_ref_005.phpt new file mode 100644 index 0000000000..513c0618df --- /dev/null +++ b/Zend/tests/magic_by_ref_005.phpt @@ -0,0 +1,18 @@ +--TEST-- +passing parameter of __isset() by ref +--FILE-- +$name)); + +echo "Done\n"; +?> +--EXPECTF-- +Fatal error: Method test::__isset() cannot take arguments by reference in %s on line %d diff --git a/Zend/tests/magic_by_ref_006.phpt b/Zend/tests/magic_by_ref_006.phpt new file mode 100644 index 0000000000..14d7d708b8 --- /dev/null +++ b/Zend/tests/magic_by_ref_006.phpt @@ -0,0 +1,18 @@ +--TEST-- +passing first parameter of __call() by ref +--FILE-- +$func(); + +echo "Done\n"; +?> +--EXPECTF-- +Fatal error: Method test::__call() cannot take arguments by reference in %s on line %d diff --git a/Zend/tests/magic_by_ref_007.phpt b/Zend/tests/magic_by_ref_007.phpt new file mode 100644 index 0000000000..c962d45813 --- /dev/null +++ b/Zend/tests/magic_by_ref_007.phpt @@ -0,0 +1,19 @@ +--TEST-- +passing second parameter of __call() by ref +--FILE-- +$func($arg); + +echo "Done\n"; +?> +--EXPECTF-- +Fatal error: Method test::__call() cannot take arguments by reference in %s on line %d diff --git a/Zend/tests/magic_by_ref_008.phpt b/Zend/tests/magic_by_ref_008.phpt new file mode 100644 index 0000000000..ba8290cba4 --- /dev/null +++ b/Zend/tests/magic_by_ref_008.phpt @@ -0,0 +1,18 @@ +--TEST-- +passing first parameter of __callstatic() by ref +--FILE-- +$func(); + +echo "Done\n"; +?> +--EXPECTF-- +Fatal error: Method test::__callstatic() cannot take arguments by reference in %s on line %d diff --git a/Zend/tests/magic_by_ref_009.phpt b/Zend/tests/magic_by_ref_009.phpt new file mode 100644 index 0000000000..3cae5e228c --- /dev/null +++ b/Zend/tests/magic_by_ref_009.phpt @@ -0,0 +1,19 @@ +--TEST-- +passing second parameter of __callstatic() by ref +--FILE-- +$func($arg); + +echo "Done\n"; +?> +--EXPECTF-- +Fatal error: Method test::__callstatic() cannot take arguments by reference in %s on line %d diff --git a/Zend/tests/magic_by_ref_010.phpt b/Zend/tests/magic_by_ref_010.phpt new file mode 100644 index 0000000000..f92e5ac175 --- /dev/null +++ b/Zend/tests/magic_by_ref_010.phpt @@ -0,0 +1,29 @@ +--TEST-- +passing arguments by ref to a method handled by __call() +--FILE-- +test(&$v); + +var_dump($v); + +echo "Done\n"; +?> +--EXPECTF-- +Strict Standards: Call-time pass-by-reference has been deprecated in %s on line %d +str +5 +int(5) +Done diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 727621bc11..09863d2685 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2012,23 +2012,47 @@ ZEND_API void zend_check_magic_method_implementation(zend_class_entry *ce, zend_ ZEND_U_EQUAL(utype, lcname, lcname_len, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME)-1) && fptr->common.num_args != 0) { zend_error(error_type, "Method %v::%s() cannot accept any arguments", ce->name, ZEND_CLONE_FUNC_NAME); } else if (lcname_len == sizeof(ZEND_GET_FUNC_NAME) - 1 && - ZEND_U_EQUAL(utype, lcname, lcname_len, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME)-1) && fptr->common.num_args != 1) { - zend_error(error_type, "Method %v::%s() must take exactly 1 argument", ce->name, ZEND_GET_FUNC_NAME); + ZEND_U_EQUAL(utype, lcname, lcname_len, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME)-1)) { + if (fptr->common.num_args != 1) { + zend_error(error_type, "Method %v::%s() must take exactly 1 argument", ce->name, ZEND_GET_FUNC_NAME); + } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) { + zend_error(error_type, "Method %v::%s() cannot take arguments by reference", ce->name, ZEND_GET_FUNC_NAME); + } } else if (lcname_len == sizeof(ZEND_SET_FUNC_NAME) - 1 && - ZEND_U_EQUAL(utype, lcname, lcname_len, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME)-1) && fptr->common.num_args != 2) { - zend_error(error_type, "Method %v::%s() must take exactly 2 arguments", ce->name, ZEND_SET_FUNC_NAME); + ZEND_U_EQUAL(utype, lcname, lcname_len, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME)-1)) { + if (fptr->common.num_args != 2) { + zend_error(error_type, "Method %v::%s() must take exactly 2 arguments", ce->name, ZEND_SET_FUNC_NAME); + } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) { + zend_error(error_type, "Method %v::%s() cannot take arguments by reference", ce->name, ZEND_SET_FUNC_NAME); + } } else if (lcname_len == sizeof(ZEND_UNSET_FUNC_NAME) - 1 && - ZEND_U_EQUAL(utype, lcname, lcname_len, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME)-1) && fptr->common.num_args != 1) { - zend_error(error_type, "Method %v::%s() must take exactly 1 argument", ce->name, ZEND_UNSET_FUNC_NAME); + ZEND_U_EQUAL(utype, lcname, lcname_len, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME)-1)) { + if (fptr->common.num_args != 1) { + zend_error(error_type, "Method %v::%s() must take exactly 1 argument", ce->name, ZEND_UNSET_FUNC_NAME); + } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) { + zend_error(error_type, "Method %v::%s() cannot take arguments by reference", ce->name, ZEND_UNSET_FUNC_NAME); + } } else if (lcname_len == sizeof(ZEND_ISSET_FUNC_NAME) - 1 && - ZEND_U_EQUAL(utype, lcname, lcname_len, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME)-1) && fptr->common.num_args != 1) { - zend_error(error_type, "Method %v::%s() must take exactly 1 argument", ce->name, ZEND_ISSET_FUNC_NAME); + ZEND_U_EQUAL(utype, lcname, lcname_len, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME)-1)) { + if (fptr->common.num_args != 1) { + zend_error(error_type, "Method %v::%s() must take exactly 1 argument", ce->name, ZEND_ISSET_FUNC_NAME); + } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) { + zend_error(error_type, "Method %v::%s() cannot take arguments by reference", ce->name, ZEND_ISSET_FUNC_NAME); + } } else if (lcname_len == sizeof(ZEND_CALL_FUNC_NAME) - 1 && - ZEND_U_EQUAL(utype, lcname, lcname_len, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)-1) && fptr->common.num_args != 2) { - zend_error(error_type, "Method %v::%s() must take exactly 2 arguments", ce->name, ZEND_CALL_FUNC_NAME); + ZEND_U_EQUAL(utype, lcname, lcname_len, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)-1)) { + if (fptr->common.num_args != 2) { + zend_error(error_type, "Method %v::%s() must take exactly 2 arguments", ce->name, ZEND_CALL_FUNC_NAME); + } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) { + zend_error(error_type, "Method %v::%s() cannot take arguments by reference", ce->name, ZEND_CALL_FUNC_NAME); + } } else if (lcname_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME) - 1 && - ZEND_U_EQUAL(utype, lcname, lcname_len, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1) && fptr->common.num_args != 2) { - zend_error(error_type, "Method %v::%s() must take exactly 2 arguments", ce->name, ZEND_CALLSTATIC_FUNC_NAME); + ZEND_U_EQUAL(utype, lcname, lcname_len, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1)) { + if (fptr->common.num_args != 2) { + zend_error(error_type, "Method %v::%s() must take exactly 2 arguments", ce->name, ZEND_CALLSTATIC_FUNC_NAME); + } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) { + zend_error(error_type, "Method %v::%s() cannot take arguments by reference", ce->name, ZEND_CALLSTATIC_FUNC_NAME); + } } else if (lcname_len == sizeof(ZEND_TOSTRING_FUNC_NAME) - 1 && ZEND_U_EQUAL(utype, lcname, lcname_len, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && fptr->common.num_args != 0) { zend_error(error_type, "Method %v::%s() cannot take arguments", ce->name, ZEND_TOSTRING_FUNC_NAME);