Mantis - Quercus
Viewing Issue Advanced Details
4047 block always 05-23-10 16:32 03-12-13 19:56
Chris Graham  
nam  
normal  
closed 4.0.7  
unable to reproduce  
none    
none  
0004047: Very complex problem with variable referencing
I have been struggling for the last 12 hours to narrow down a very complex problem. Quercus is taking variable references when it should not be, inside complex array/object structures. Unfortunately I could not narrow it down in the time I've spent because it is such as weird problem related possibly to scope in loops/functions, nesting arrangements in the data structures, and the way data is copied back through (falsely held) references.
I have attached a complex test case. It highlights the difference in behaviour between Zend PHP and Quercus.

I think this is a really critical problem, as it seems impossible to remedy or detect this in an easy way and likely affects a lot of systems with complex parse structures.
 test.php [^] (3,233 bytes) 05-23-10 16:32

Notes
(0004620)
sblommers   
05-01-10 03:12   
Hi Chris, I am having the same sort of (critical) problem using references (which works partially it seems) using Drupal 6.16 against latest in SVN. I'm trying to pinpoint the occurance of this bug for a day or so. Currently the bug tracker has a problem when uploading files, .. could you paste the contents of the test.php here or email it to me at sebastiaan.blommers@gmail.com ?

Thank you!

Sebastiaan
(0004621)
sblommers   
05-01-10 03:15   
What I forgot to mention is that I have a problem with a php object after referencing to it from a method and cloning it (copy object).

I hope you can send me the test.php quickly for I'm eager to solve/find this issue (and it's cause) as well.
(0004622)
sblommers   
05-01-10 06:46   
<?php

ini_set('display_errors','1');
error_reporting(E_ALL);


define('SYMBOL_PARSE_NAME',0);
define('SYMBOL_PARSE_PARAM',1);

define('TC_SYMBOL',0);
define('TC_KNOWN',1);
define('TC_PARAMETER',3);

// Should display 101112 ; on Quercus displays 101010
for ($i=10;$i<13;$i++)
{
    $x=do_template(array(
        'VAR'=>strval($i),
    ));
    echo $x->bits[0][2][0]->bits[0][1];
}

function read_single_uncompiled_symbol($text,&$symbol_pos,$symbol_len)
{
    $type=TC_PARAMETER;
    $mode=SYMBOL_PARSE_NAME;
    $name='';
    $param=array(); // Note about Quercus: I have simplified the code to assume there's only a single param to go in here. However I did find if the array is removed and we write into a direct variable then the bug does not happen.
    $starting=true;

    while (true)
    {
        $next=$text[$symbol_pos];
        ++$symbol_pos;

        switch ($mode)
        {
            case SYMBOL_PARSE_PARAM:
                switch ($next)
                {
                    case '}':
                        $ret=array($type,$name,$param);
                        return $ret;

                    case '{':
                        $ret=read_single_uncompiled_symbol($text,$symbol_pos,$symbol_len);
                        $param[0]->bits[]=$ret;
                        break;

                    default:
                        $param[0]->attach($next);
                }
                break;

            case SYMBOL_PARSE_NAME:
                if ($starting)
                {
                    $starting=false;
                    switch($next)
                    {
                        case '$':
                            $type=TC_SYMBOL;
                            continue 2;
                    }
                }
                switch ($next)
                {
                    case '}':
                        $ret=array($type,$name,array());
                        return $ret;

                    case ',':
                        $mode=SYMBOL_PARSE_PARAM;
                        $param[0]=new ocp_tempcode();
                        break;

                    default:
                        $name.=$next;
                }
                break;
        }

        if ($symbol_pos>=$symbol_len)
        {
            return array(TC_KNOWN,'',array());
        }
    }
}

function do_template($parameters)
{
    static $TEMPLATE_CACHE=NULL;
    $codename='test';

    if (isset($TEMPLATE_CACHE)) // Primed cache. However on Quercus, as the call to "->bind" tampered with the cache data too, this is already hard-bound and thus returns the same result
    {
        $_data=$TEMPLATE_CACHE->bind($parameters,$codename);
        return $_data;
    }


    // Re-parse

    $text='{$BLAH,{VAR}}'; // I've hard-coded a template for this bug report, and simplifed the parsing to just assume it is reading in a single symbol
    $out=new ocp_tempcode();
    $symbol_len=strlen($text);
    $symbol_pos=1;
    $ret=read_single_uncompiled_symbol($text,$symbol_pos,$symbol_len);
    $out->bits[]=$ret;
    
    $TEMPLATE_CACHE=$out;

    return $out->bind($parameters,$codename); // On Quercus, $out ends up altered, which should be impossible
}

class ocp_tempcode
{
    var $bits=array(); // A list of tripes; each triple is: component type, name/data, binding parameters.

    function attach($attach)
    {
        $this->bits[]=array(TC_KNOWN,$attach,array());
    }

    function bind(&$parameters,$codename)
    {
        $out=new ocp_tempcode();

        foreach ($this->bits as $bit)
        {
            if ($bit[0]==TC_SYMBOL) // Binds data to symbols
            {
                foreach ($bit[2] as $i=>$param)
                {
                    $bit[2][$i]=$param->bind($parameters,$codename); // On Quercus "$param->bind($parameters,$codename);" is actually modifying $param, which should be impossible
                }
            }

            if ($bit[0]==TC_PARAMETER)
            {
                $out->attach($parameters[$bit[1]]); // The actual binding operation
            } else
            {
                $out->bits[]=$bit;
            }
        }

        return $out;
    }
}
(0005243)
Chris Graham   
05-14-11 09:56   
I thought I'd give Quercus another try, but this is still happening :(.
(0005244)
sblommers   
05-15-11 02:00   
I tried this again some time earlier. These kind of parse issue were such a risk I removed Quercus in our project and I'm using php5-fpm instead. Now we are using services to get data from and to php. It's a shame Quercus does not have a nice testing suite to do a correct regression test (see php unit tests within php packages).

Good luck to you Chris.

Hopefully Quercus will grow up any time soon.
(0006218)
nam   
03-12-13 19:56   
Unable to reproduce in 4.0.35. Thanks Chris and everyone else for the detailed bug report. I believe this issue was fixed a few months back. Drupal 6 works like a charm on Quercus. If you run into any new issues, I promise to look into them immediately.