php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68185 'PHP Fatal error: Inconsistent insteadof definition.' - incorrectly triggered
Submitted: 2014-10-08 09:14 UTC Modified: 2014-11-21 18:05 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:2 (100.0%)
From: marc at dotfive dot co dot uk Assigned: jpauli (profile)
Status: Closed Package: Class/Object related
PHP Version: 5.6.1 OS: Debian Wheezy/Jessie
Private report: No CVE-ID: None
 [2014-10-08 09:14 UTC] marc at dotfive dot co dot uk
Description:
------------
'PHP Fatal error:  Inconsistent insteadof definition.' - This error is triggered incorrectly and very unpredictably on classes with many traits. Reproducing this bug is very difficult, as the outcome is affected by seemingly irrelevant things. This has been found in versions 5.4 through to 5.6.1 and appears to have been introduced by commit 520d07d86a7520c970e18480ed0237c6253bd097, which fixed Bug #61052: "missing error check in trait 'insteadof' clause"

This inconsistant behaviour appears to be caused by an incorrect index when checking if the included trait method is in exclude_from_classes. In the code below from zend_compile.c cur_precedence->exclude_from_classes[i] should, I believe, be cur_precedence->exclude_from_classes[j] (i.e. the 'i' should be a 'j'):

zend_compile.c
----------------------------
/* make sure that the trait method is not from a class mentioned in
exclude_from_classes, for consistency */
if (cur_precedence->trait_method->ce == cur_precedence->exclude_from_classes[i]) {
	zend_error(E_COMPILE_ERROR,
		"Inconsistent insteadof definition. "

Test script:
---------------
The following script is split across two files, 'test' and 'class.php'. I have been unable to create a script in a single file that incorrectly triggers the error. The first file, test, creates a bunch of empty classes and includes class.php, which defines a classes with traits and uses 'insteadof'. Changing the number of empty classes that are created in test changes whether or not the error triggers, as does changing the number of traits in class.php. Even seemingly irrelevant things change whether the error triggers; adding something like an 'echo' at the beginning of the script, or running the script from a different directory changes this behaviour.

test:
------------------------
#!/usr/bin/php -q
<?php

$i = 17;

while ($i--) {
	
	eval('class c' . $i . ' {}');
	
}

require_once("class.php");

die("End");



class.php:
-----------------------
<?php

namespace	SPACE;

trait trait0 { public function methodName() {} }
trait trait1 { public function methodName() {} }
trait trait2 { public function methodName() {} }
trait trait3 { public function methodName() {} }
trait trait4 { public function methodName() {} }
trait trait5 { public function methodName() {} }
trait trait6 { public function methodName() {} }
trait trait7 { public function methodName() {} }

class c {
	
	use			trait0,
				trait1,
				trait2,
				trait3,
				trait4,
				trait5,
				trait6,
				trait7
		{
				trait0::methodName insteadof trait1;
				trait0::methodName insteadof trait2;
				trait0::methodName insteadof trait3;
				trait0::methodName insteadof trait4;
				trait0::methodName insteadof trait5;
				trait0::methodName insteadof trait6;
				trait0::methodName insteadof trait7;
				
		}
	
}

Expected result:
----------------
# ./test
End

Actual result:
--------------
# ./test
PHP Fatal error:  Inconsistent insteadof definition. The method methodName is to be used from SPACE\trait0, but SPACE\trait0 is also on the exclude list in /root/class.php on line 79

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-10-24 15:50 UTC] aharvey@php.net
-Assigned To: +Assigned To: aharvey
 [2014-10-29 13:43 UTC] jpauli@php.net
This effectively fixes it.
The fact that it got random part is true.

Having i instead of j in the loop does add a very different meaning to the code.
Depending on random, you effectively can hit this bug, this is why having a test case for it is very hard.

Anyway, this patch fixes the behavior :
https://github.com/jpauli/php-src/compare/68185
 [2014-11-21 15:06 UTC] jpauli@php.net
Automatic comment on behalf of jpauli
Revision: http://git.php.net/?p=php-src.git;a=commit;h=cd3b46f28af49e5eaaa687d5d186e641ce147853
Log: Fix #68185 - Inconsistent insteadof definition
 [2014-11-21 15:06 UTC] jpauli@php.net
-Status: Assigned +Status: Closed
 [2014-11-21 15:07 UTC] jpauli@php.net
Automatic comment on behalf of jpauli
Revision: http://git.php.net/?p=php-src.git;a=commit;h=cd3b46f28af49e5eaaa687d5d186e641ce147853
Log: Fix #68185 - Inconsistent insteadof definition
 [2014-11-21 15:07 UTC] jpauli@php.net
Automatic comment on behalf of jpauli
Revision: http://git.php.net/?p=php-src.git;a=commit;h=af3a42022b34cd595d3231a845a7d8562f4a3523
Log: Fix #68185 - Inconsistent insteadof definition
 [2014-11-21 15:07 UTC] jpauli@php.net
Automatic comment on behalf of jpauli
Revision: http://git.php.net/?p=php-src.git;a=commit;h=cd3b46f28af49e5eaaa687d5d186e641ce147853
Log: Fix #68185 - Inconsistent insteadof definition
 [2014-11-21 15:22 UTC] jpauli@php.net
-Status: Closed +Status: Feedback
 [2014-11-21 15:22 UTC] jpauli@php.net
Please try using this snapshot:

  http://snaps.php.net/php5.5-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/


 [2014-11-21 18:05 UTC] aharvey@php.net
-Assigned To: aharvey +Assigned To: jpauli
 [2014-11-26 16:21 UTC] ab@php.net
Automatic comment on behalf of jpauli
Revision: http://git.php.net/?p=php-src.git;a=commit;h=af3a42022b34cd595d3231a845a7d8562f4a3523
Log: Fix #68185 - Inconsistent insteadof definition
 [2014-11-26 16:21 UTC] ab@php.net
-Status: Feedback +Status: Closed
 [2014-11-26 16:21 UTC] ab@php.net
Automatic comment on behalf of jpauli
Revision: http://git.php.net/?p=php-src.git;a=commit;h=cd3b46f28af49e5eaaa687d5d186e641ce147853
Log: Fix #68185 - Inconsistent insteadof definition
 [2016-07-20 11:40 UTC] davey@php.net
Automatic comment on behalf of jpauli
Revision: http://git.php.net/?p=php-src.git;a=commit;h=af3a42022b34cd595d3231a845a7d8562f4a3523
Log: Fix #68185 - Inconsistent insteadof definition
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC