diff options
author | Antony Dovgal <tony2001@php.net> | 2007-08-31 12:36:14 +0000 |
---|---|---|
committer | Antony Dovgal <tony2001@php.net> | 2007-08-31 12:36:14 +0000 |
commit | 90d58d466880e16df63d0ebe00b4c4db60b01184 (patch) | |
tree | ba293cebcdd924a4418117215f199e5949d8c15c | |
parent | 39bceffc4a318469c5333cfd5425b9e4aac196c6 (diff) | |
download | php-git-90d58d466880e16df63d0ebe00b4c4db60b01184.tar.gz |
MFH: prohibit arguments by ref in magic methods
-rw-r--r-- | Zend/tests/magic_by_ref_001.phpt | 17 | ||||
-rw-r--r-- | Zend/tests/magic_by_ref_002.phpt | 16 | ||||
-rw-r--r-- | Zend/tests/magic_by_ref_003.phpt | 17 | ||||
-rw-r--r-- | Zend/tests/magic_by_ref_004.phpt | 18 | ||||
-rw-r--r-- | Zend/tests/magic_by_ref_005.phpt | 18 | ||||
-rw-r--r-- | Zend/tests/magic_by_ref_006.phpt | 18 | ||||
-rw-r--r-- | Zend/tests/magic_by_ref_007.phpt | 19 | ||||
-rw-r--r-- | Zend/tests/magic_by_ref_010.phpt | 28 | ||||
-rw-r--r-- | Zend/zend_API.c | 40 |
9 files changed, 181 insertions, 10 deletions
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-- +<?php + +class test { + function __set(&$name, $val) { } +} + +$t = new test; +$name = "prop"; +$t->$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-- +<?php + +class test { + function __set($name, &$val) { } +} + +$t = new test; +$t->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-- +<?php + +class test { + function __get(&$name) { } +} + +$t = new test; +$name = "prop"; +var_dump($t->$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-- +<?php + +class test { + function __unset(&$name) { } +} + +$t = new test; +$name = "prop"; + +var_dump($t->$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-- +<?php + +class test { + function __isset(&$name) { } +} + +$t = new test; +$name = "prop"; + +var_dump(isset($t->$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-- +<?php + +class test { + function __call(&$name, $args) { } +} + +$t = new test; +$func = "foo"; + +$t->$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-- +<?php + +class test { + function __call($name, &$args) { } +} + +$t = new test; +$func = "foo"; +$arg = 1; + +$t->$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_010.phpt b/Zend/tests/magic_by_ref_010.phpt new file mode 100644 index 0000000000..48f235355c --- /dev/null +++ b/Zend/tests/magic_by_ref_010.phpt @@ -0,0 +1,28 @@ +--TEST-- +passing arguments by ref to a method handled by __call() +--FILE-- +<?php + +class Foo { + function __call($method, $args) + { + print $args[0]."\n"; + $args[0] = 5; + print $args[0]."\n"; + return true; + } +} + +$v = 'str'; +$o = new Foo(); +$o->test(&$v); + +var_dump($v); + +echo "Done\n"; +?> +--EXPECTF-- +str +5 +int(5) +Done diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 5092e8ca72..1d9f9b2917 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1593,16 +1593,36 @@ ZEND_API void zend_check_magic_method_implementation(zend_class_entry *ce, zend_ zend_error(error_type, "Destructor %s::%s() cannot take arguments", ce->name, ZEND_DESTRUCTOR_FUNC_NAME); } else if (name_len == sizeof(ZEND_CLONE_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME)) && fptr->common.num_args != 0) { zend_error(error_type, "Method %s::%s() cannot accept any arguments", ce->name, ZEND_CLONE_FUNC_NAME); - } else if (name_len == sizeof(ZEND_GET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME)) && fptr->common.num_args != 1) { - zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name, ZEND_GET_FUNC_NAME); - } else if (name_len == sizeof(ZEND_SET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME)) && fptr->common.num_args != 2) { - zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ce->name, ZEND_SET_FUNC_NAME); - } else if (name_len == sizeof(ZEND_UNSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME)) && fptr->common.num_args != 1) { - zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name, ZEND_UNSET_FUNC_NAME); - } else if (name_len == sizeof(ZEND_ISSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME)) && fptr->common.num_args != 1) { - zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name, ZEND_ISSET_FUNC_NAME); - } else if (name_len == sizeof(ZEND_CALL_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)) && fptr->common.num_args != 2) { - zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ce->name, ZEND_CALL_FUNC_NAME); + } else if (name_len == sizeof(ZEND_GET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME))) { + if (fptr->common.num_args != 1) { + zend_error(error_type, "Method %s::%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 %s::%s() cannot take arguments by reference", ce->name, ZEND_GET_FUNC_NAME); + } + } else if (name_len == sizeof(ZEND_SET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME))) { + if (fptr->common.num_args != 2) { + zend_error(error_type, "Method %s::%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 %s::%s() cannot take arguments by reference", ce->name, ZEND_SET_FUNC_NAME); + } + } else if (name_len == sizeof(ZEND_UNSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME))) { + if (fptr->common.num_args != 1) { + zend_error(error_type, "Method %s::%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 %s::%s() cannot take arguments by reference", ce->name, ZEND_UNSET_FUNC_NAME); + } + } else if (name_len == sizeof(ZEND_ISSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME))) { + if (fptr->common.num_args != 1) { + zend_error(error_type, "Method %s::%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 %s::%s() cannot take arguments by reference", ce->name, ZEND_ISSET_FUNC_NAME); + } + } else if (name_len == sizeof(ZEND_CALL_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME))) { + if (fptr->common.num_args != 2) { + zend_error(error_type, "Method %s::%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 %s::%s() cannot take arguments by reference", ce->name, ZEND_CALL_FUNC_NAME); + } } } |