Bug #71248 [Asn->Csd]: Wrong interface is enforced
| From: | dmitry@php.net | Date: | Wed, 13 Jan 2016 08:43:05 +0000 |
| Subject: | Bug #71248 [Asn->Csd]: Wrong interface is enforced | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-198619@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=71248&edit=1
ID: 71248
Updated by: dmitry@php.net
Reported by: norbert at linuxnetworks dot de
Summary: Wrong interface is enforced
-Status: Assigned
+Status: Closed
Type: Bug
Package: Class/Object related
Operating System: Ubuntu 14.04
PHP Version: 7.0.1
Assigned To: dmitry
Block user comment: N
Private report: N
New Comment:
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=50be2c89bed61a1928cd1dd0c226fe62769344dd
Log: Fixed bug #71248 (Wrong interface is enforced)
Previous Comments:
------------------------------------------------------------------------
[2016-01-12 13:33:40] dmitry@php.net
This patch should fix the problem
https://gist.github.com/dstogov/81ded758484a608b831b
@nikic: please review.
------------------------------------------------------------------------
[2016-01-12 01:10:05] dmitry@php.net
We should try to lazely duplicate op_array, only in case of op_array.prototype modification (copy on
write).
------------------------------------------------------------------------
[2016-01-11 21:42:37] nikic@php.net
@dmitry: Regarding the last comment, do you see a better way to solve it, short of always copying
the op_array struct during inheritance?
------------------------------------------------------------------------
[2016-01-05 15:26:47] nikic@php.net
The problem is that in PHP 7 we will share the op_array between inherited class methods if it does
not use static variables, under the assumption that all their members will stay the same.
However this assumption is not true in this case, namely function->common.prototype may differ.
In this case Provider\Base::__construct() has no prototype, while
Provider\Delivery\Manual::__construct() [inherited from Provider\Base::__construct()] has
Provider\Factory\Iface::__construct() as the prototype. As the op_array is shared between both this
inheritance will clobber common.prototype for Provider\Base::__construct() as well. This then causes
the inheritance error in Provider\Decorator\Base.
We could fix it by simply always using a separate op_array (i.e. drop http://lxr.php.net/xref/PHP_MASTER/Zend/zend_inheritance.c#77).
Is there a better way to somehow only copy if we need a different prototype?
------------------------------------------------------------------------
[2016-01-03 14:05:36] nikic@php.net
Ooops, I pasted the non-reduced code. Here's the correct version:
<?php
namespace Provider;
interface Iface { }
abstract class Base {
public function __construct(\Item\Iface $serviceItem) { }
}
namespace Provider\Factory;
interface Iface {
public function __construct(\Item\Iface $serviceItem);
}
namespace Provider\Delivery;
interface Iface extends \Provider\Iface, \Provider\Factory\Iface { }
abstract class Base extends \Provider\Base { }
class Manual extends \Provider\Delivery\Base implements \Provider\Delivery\Iface { }
$code = <<<'PHP'
namespace Provider\Decorator;
abstract class Base extends \Provider\Base {
public function __construct(\Provider\Iface $provider, \Item\Iface $serviceItem) { }
}
PHP;
eval($code);
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=71248
--
Edit this bug report at https://bugs.php.net/bug.php?id=71248&edit=1