summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Dovgal <tony2001@php.net>2007-08-31 12:36:14 +0000
committerAntony Dovgal <tony2001@php.net>2007-08-31 12:36:14 +0000
commit90d58d466880e16df63d0ebe00b4c4db60b01184 (patch)
treeba293cebcdd924a4418117215f199e5949d8c15c
parent39bceffc4a318469c5333cfd5425b9e4aac196c6 (diff)
downloadphp-git-90d58d466880e16df63d0ebe00b4c4db60b01184.tar.gz
MFH: prohibit arguments by ref in magic methods
-rw-r--r--Zend/tests/magic_by_ref_001.phpt17
-rw-r--r--Zend/tests/magic_by_ref_002.phpt16
-rw-r--r--Zend/tests/magic_by_ref_003.phpt17
-rw-r--r--Zend/tests/magic_by_ref_004.phpt18
-rw-r--r--Zend/tests/magic_by_ref_005.phpt18
-rw-r--r--Zend/tests/magic_by_ref_006.phpt18
-rw-r--r--Zend/tests/magic_by_ref_007.phpt19
-rw-r--r--Zend/tests/magic_by_ref_010.phpt28
-rw-r--r--Zend/zend_API.c40
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);
+ }
}
}