prohibit arguments by ref in magic methods

This commit is contained in:
Antony Dovgal 2007-08-31 12:36:00 +00:00
parent 98bb2b0d9e
commit e8a72ac5e1
11 changed files with 225 additions and 12 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,18 @@
--TEST--
passing first parameter of __callstatic() by ref
--FILE--
<?php
class test {
function __callstatic(&$name, $args) { }
}
$t = new test;
$func = "foo";
$t->$func();
echo "Done\n";
?>
--EXPECTF--
Fatal error: Method test::__callstatic() cannot take arguments by reference in %s on line %d

View File

@ -0,0 +1,19 @@
--TEST--
passing second parameter of __callstatic() by ref
--FILE--
<?php
class test {
function __callstatic($name, &$args) { }
}
$t = new test;
$func = "foo";
$arg = 1;
$t->$func($arg);
echo "Done\n";
?>
--EXPECTF--
Fatal error: Method test::__callstatic() cannot take arguments by reference in %s on line %d

View File

@ -0,0 +1,29 @@
--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--
Strict Standards: Call-time pass-by-reference has been deprecated in %s on line %d
str
5
int(5)
Done

View File

@ -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);