From e62bb0325763d9847847dd198e05c9b3147caf05 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 19 Mar 2013 12:48:23 +0400 Subject: [PATCH] Fixed bug #64417 (ArrayAccess::&offsetGet() in a trait causes fatal error) --- NEWS | 2 ++ Zend/tests/bug64417.phpt | 39 +++++++++++++++++++++++++++++++++++++++ Zend/zend_compile.c | 2 +- 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/bug64417.phpt diff --git a/NEWS b/NEWS index fd05e22e012..75b588bfaed 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2013, PHP 5.4.14 - Core + . Fixed bug #64417 (ArrayAccess::&offsetGet() in a trait causes fatal error). + (Dmitry) . Fixed bug #64370 (microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT']). (Anatol) diff --git a/Zend/tests/bug64417.phpt b/Zend/tests/bug64417.phpt new file mode 100644 index 00000000000..f3ef740b43e --- /dev/null +++ b/Zend/tests/bug64417.phpt @@ -0,0 +1,39 @@ +--TEST-- +Bug #64417 (BC break: ArrayAccess::&offsetGet() in a trait causes fatal error) +--FILE-- +container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + public function offsetExists($offset) { + return isset($this->container[$offset]); + } + public function offsetUnset($offset) { + unset($this->container[$offset]); + } + public function &offsetGet($offset) { + $result = null; + if (isset($this->container[$offset])) { + $result = &$this->container[$offset]; + } + return $result; + } +} + +class obj implements ArrayAccess { + use aa; +} + +$o = new obj; +$o['x'] = 1; +++$o['x']; +echo $o['x'], "\n"; +--EXPECT-- +2 + diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 0a1749dbd87..766a2de01a3 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3634,7 +3634,7 @@ static zend_bool zend_traits_method_compatibility_check(zend_function *fn, zend_ zend_uint other_flags = other_fn->common.scope->ce_flags; return zend_do_perform_implementation_check(fn, other_fn TSRMLS_CC) - && zend_do_perform_implementation_check(other_fn, fn TSRMLS_CC) + && ((other_fn->common.scope->ce_flags & ZEND_ACC_INTERFACE) || zend_do_perform_implementation_check(other_fn, fn TSRMLS_CC)) && ((fn_flags & (ZEND_ACC_FINAL|ZEND_ACC_STATIC)) == (other_flags & (ZEND_ACC_FINAL|ZEND_ACC_STATIC))); /* equal final and static qualifier */ }