From 9d25e7ee7b52645d33a28bed269ea11d102b88a2 Mon Sep 17 00:00:00 2001 From: Etienne Kneuss Date: Wed, 3 Nov 2010 15:40:24 +0000 Subject: [PATCH] Fixed covariance of return-by-ref constraints --- NEWS | 1 + Zend/tests/objects_032.phpt | 40 +++++++++++++++++++++++++++++++++++++ Zend/zend_compile.c | 5 ++++- 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/objects_032.phpt diff --git a/NEWS b/NEWS index 61307e58c8..38ec9ea4f0 100644 --- a/NEWS +++ b/NEWS @@ -50,6 +50,7 @@ large amount of data) (CVE-2010-3710). (Adam) - Fixed ReflectionProperty::isDefault() giving a wrong result for properties obtained with ReflectionClass::getProperties(). (Gustavo) +- Fixed covariance of return-by-ref constraints. (Etienne) - Fixed bug #53198 (changing INI setting "from" with ini_set did not have any effect). (Gustavo) diff --git a/Zend/tests/objects_032.phpt b/Zend/tests/objects_032.phpt new file mode 100644 index 0000000000..e5e3ecadb2 --- /dev/null +++ b/Zend/tests/objects_032.phpt @@ -0,0 +1,40 @@ +--TEST-- +Covariant return-by-ref constraints +--FILE-- +foo[$n]; + } + + public function offsetSet($n, $v) { + } + public function offsetUnset($n) { + } + public function offsetExists($n) { + } +} + +$a = new A; + +$a['foo']['bar'] = 2; + +var_dump($a); + +?> +==DONE== +--EXPECTF-- +object(A)#1 (1) { + ["foo"]=> + array(1) { + ["foo"]=> + array(1) { + ["bar"]=> + int(2) + } + } +} +==DONE== diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index febf2da905..799b77410b 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2557,7 +2557,8 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c return 0; } - if (fe->common.return_reference != proto->common.return_reference) { + /* by-ref constraints on return values are covariant */ + if (proto->common.return_reference && !fe->common.return_reference) { return 0; } @@ -2581,6 +2582,8 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c /* Only one has an array type hint and the other one doesn't */ return 0; } + + /* by-ref constraints on arguments are invariant */ if (fe->common.arg_info[i].pass_by_reference != proto->common.arg_info[i].pass_by_reference) { return 0; } -- 2.40.0