php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #65845 Error when Zend Opcache Optimizer is fully enabled
Submitted: 2013-10-06 11:38 UTC Modified: 2013-10-10 11:39 UTC
From: bruno+php at ahennezel dot info Assigned: dmitry
Status: Closed Package: opcache
PHP Version: 5.5.4 OS: Linux 3.11.2-1-ARCH
Private report: No CVE-ID:
 [2013-10-06 11:38 UTC] bruno+php at ahennezel dot info
Description:
------------
With the SPIP CMS V3, the default optimization level 
opcache.optimization_level=0xffffffff
and 
opcache.optimization_level=0xffffffef
give different results.


Test script:
---------------
I dont know how to test directly in PHP, but here is a very short SPIP snippet which brings out the problem. Put in the SPIP's sommaire.html skeleton : 

#SET{var,value}
[(#GET{var})]

With opcache.optimization_level=0xffffffff the result is empty.
With opcache.optimization_level=0xffffffff the result is "value".








Expected result:
----------------
I expect the content "value"

Actual result:
--------------
The content is empty

Patches

bug65845.patch (last revision 2013-10-10 04:29 UTC) by laruence@php.net)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-10-06 18:10 UTC] bruno+php at ahennezel dot info
Typo : With opcache.optimization_level=0xffffffef the result is "value".
 [2013-10-06 18:13 UTC] bruno+php at ahennezel dot info
-Package: optimizer +Package: opcache
 [2013-10-06 18:13 UTC] bruno+php at ahennezel dot info
Wrong package : Opcache
 [2013-10-08 05:56 UTC] laruence@php.net
-Status: Open +Status: Feedback
 [2013-10-08 05:56 UTC] laruence@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.

hmm, are you able to get the compiled SPIP view file?  it must be a PHP script which can be used to reproduce this problem?
 [2013-10-08 10:17 UTC] brunobergot at gmail dot com
Hi Laurence,

Here is a script that show the bug in action :

<h1>APC BUG</h1>
<?php
// Expected :
// APC BUG
// This should echo empty string: ><
// This should echo "tutu" string: >tutu<

// Works as expected with opcache.optimization_level=0xffffffef in php.ini


function table_valeur($table, $cle, $defaut='') {
    foreach (explode('/', $cle) as $k) {

        $table = is_string($table) ? @unserialize($table) : $table;

        if (is_object($table)) {
            $table =  (($k !== "") and isset($table->$k)) ? $table->$k : $defaut;
        } elseif (is_array($table)) {
            $table = isset($table[$k]) ? $table[$k] : $defaut;
        } else {
            $table = $defaut;
        }
    }
    return $table;
}

function vide($texte){
    return "";
}

echo "This should echo empty string: &gt;".vide($Pile['vars'][(string)'toto'] = 'tutu')."&lt;<br />";
echo "This should echo \"tutu\" string: &gt;".table_valeur($Pile['vars'],'toto')."&lt;<br />";

?>
 [2013-10-08 10:30 UTC] brunobergot at gmail dot com
Hi again Laruence,

We found that the problem comes form the cast in $Pile['vars'][(string)'toto']. With this news test script it works as expected :

<h1>APC BUG</h1>
<?php
// Expected :
// APC BUG
// This should echo empty string: ><
// This should echo "tutu" string: >tutu<

// Works as expected with opcache.optimization_level=0xffffffef in php.ini


function table_valeur($table, $cle, $defaut='') {
var_dump($table);
var_dump($cle);
var_dump($table[$cle]);
    foreach (explode('/', $cle) as $k) {

        $table = is_string($table) ? @unserialize($table) : $table;

        if (is_object($table)) {
            $table =  (($k !== "") and isset($table->$k)) ? $table->$k : $defaut;
        } elseif (is_array($table)) {
            $table = isset($table[$k]) ? $table[$k] : $defaut;
        } else {
            $table = $defaut;
        }
    }
    return $table;
}

function vide($texte){
    return "";
}

echo "This should echo empty string: &gt;".vide($Pile['vars']['toto'] = 'tutu')."&lt;<br />";
echo "This should echo \"tutu\" string: &gt;".table_valeur($Pile['vars'],'toto')."&lt;<br />";

?>
 [2013-10-08 10:44 UTC] brunobergot at gmail dot com
Me again, here is a last test script that work without changing opcache.optimization_level :

<h1>APC BUG</h1>
<?php
// Expected :
// APC BUG
// This should echo empty string: ><
// This should echo "tutu" string: >tutu<


function table_valeur($table, $cle, $defaut='') {
    foreach (explode('/', $cle) as $k) {

        $table = is_string($table) ? @unserialize($table) : $table;

        if (is_object($table)) {
            $table =  (($k !== "") and isset($table->$k)) ? $table->$k : $defaut;
        } elseif (is_array($table)) {
            $table = isset($table[$k]) ? $table[$k] : $defaut;
        } else {
            $table = $defaut;
        }
    }
    return $table;
}

function vide($texte){
    return "";
}

echo "This should echo empty string: &gt;".vide($Pile['vars'][$zzz=(string)'toto'] = 'tutu')."&lt;<br />";
echo "This should echo \"tutu\" string: &gt;".table_valeur($Pile['vars'],'toto')."&lt;<br />";

?>
 [2013-10-08 11:02 UTC] laruence@php.net
hmm, I run this with opcache enable, and fully optimizer. 

seems the output is expected?

"
$ php55 -d opcache.enable=1 -d opcache.optimization_level=0xffffffff /tmp/1.php
This should echo empty string:
This should echo "tutu" string: tutu
"
 [2013-10-08 11:05 UTC] laruence@php.net
Please try using this snapshot:

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

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

please try with the latest snapshot of php5.5 in git
 [2013-10-08 13:34 UTC] guy dot cesaro at gmail dot com
Hello Laruence,

I've tried with php-cli (windows and ubuntu), the output is ok.

Antoher try with : Apache/2.4.6 (Ubuntu) + PHP Version 5.5.4-1+debphp.org~raring+1 and the output is not ok.

Can you please try the script with http server ?
 [2013-10-09 02:35 UTC] laruence@php.net
that doesn't make sense, are you sure they are the same PHP?
 [2013-10-09 09:07 UTC] brunobergot at gmail dot com
Hi Laruence, i'm pretty sure that Guy use the same php script cause i've sended it to him ;)
 [2013-10-09 11:42 UTC] cedric at yterium dot com
@laruence
what makes sense is to use the right flag for cli runtime : opcache.enable is for non-cli PHP whereas opcache.enable_cli is for cli version.

Just try with the good option in order to see the bug :

$ php55 -d opcache.enable_cli=1 -d opcache.optimization_level=0xffffffff /tmp/1.php
 [2013-10-09 12:02 UTC] guy dot cesaro at gmail dot com
Using the right flag to enable opcache with php-cli, the output is also incorrect. I tried with php 5.5.3, 5.5.4 and the latest snapshot.

thank you for your help Cedric
 [2013-10-09 16:05 UTC] laruence@php.net
sorry, I used wrong branch of opcache. and now I can reproduce that.
 [2013-10-09 16:06 UTC] laruence@php.net
-Assigned To: +Assigned To: dmitry
 [2013-10-09 16:06 UTC] laruence@php.net
I have got a fix:

$ git diff
diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c
index 795b954..9ef7d8a 100644
--- a/ext/opcache/Optimizer/pass1_5.c
+++ b/ext/opcache/Optimizer/pass1_5.c
@@ -157,8 +157,8 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
 			if (ZEND_OP1_TYPE(opline) == IS_CONST &&
 				opline->extended_value != IS_ARRAY &&
 				opline->extended_value != IS_OBJECT &&
-				opline->extended_value != IS_RESOURCE) {
-				/* cast of constant operand */
+				opline->extended_value != IS_RESOURCE &&
+				Z_TYPE(ZEND_OP1_LITERAL(opline)) != opline->extended_value) {
 				zval res;
 				res = ZEND_OP1_LITERAL(opline);
 				zval_copy_ctor(&res);


to Dmitry:  this is because precalculted hash is lost while doing a nop cast...

could you please review it?
 [2013-10-09 16:08 UTC] laruence@php.net
more simple reproduce script:

<?php
function table_valeur($table) {
    return $table['toto'];
}

$Pile['vars'][(string)'toto'] = 'tutu';
var_dump(table_valeur($Pile['vars']));
 [2013-10-10 04:29 UTC] laruence@php.net
The following patch has been added/updated:

Patch Name: bug65845.patch
Revision:   1381379379
URL:        https://bugs.php.net/patch-display.php?bug=65845&patch=bug65845.patch&revision=1381379379
 [2013-10-10 11:33 UTC] dmitry@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=ef8cf76815e10db08d07897296c09b925a1511a1
Log: Fixed bug #65845 (Error when Zend Opcache Optimizer is fully enabled).
 [2013-10-10 11:33 UTC] dmitry@php.net
-Status: Feedback +Status: Closed
 [2013-10-10 11:39 UTC] dmitry@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 [2013-10-10 11:42 UTC] brunobergot at gmail dot com
Thanks for the patch laruence and dmitry :)
 [2013-11-17 09:30 UTC] laruence@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=ef8cf76815e10db08d07897296c09b925a1511a1
Log: Fixed bug #65845 (Error when Zend Opcache Optimizer is fully enabled).
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Wed Apr 16 18:01:53 2014 UTC