Categories > TinyButStrong general >

script=;subtp problem revisteted (Sorry for double-posting)

The forum is closed. Please use Stack Overflow for submitting new questions. Use tags: tinybutstrong , opentbs
By: mgb
Date: 2007-12-25
Time: 22:52

script=;subtp problem revisteted (Sorry for double-posting)

Hi Skrol29,
I was wondering if you saw this post.
http://tinybutstrong.com/forum.php?msg_id=8518

There are some problems regarding strings in subtpl.
If you take a strlen() on a $CurrPrm['Key'] it will return the length of the tbs block []
not the value it should point at.

There are some examples in the tread.
/mgb
By: Skrol29
Date: 2007-12-27
Time: 00:26

Re: script=;subtp problem revisteted (Sorry for double-posting)

Hi Mgb and TomH,

It seems to be a very very strange PHP bug.
I'm about to report it to bugs.php.net.

Here is a small standalone test to reproduce this bug.
If you can reproduce the bug, can you give your PHP version and OS version in this thread? Regards,
My is PHP 5.2.4, Windows Vista (sorry).
<?php


$Txt = '';
f_Action1($Txt);
f_Action2($Txt);
echo $Txt;

function f_Action1(&$Txt) {

  $z = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';

    echo "value before={".$z."} <br>\r\n";

    ob_start();

    echo "value after={".$z."} <br>\r\n"; // Bug here : it is like Action2() has been applied to $z
   
    echo "serialize={".serialize($z)."} <br>\r\n"; // Bug here : the serialization is inconsistent between size and value.
   
    $Txt = ob_get_contents();
    ob_end_clean();

}

function f_Action2(&$Txt) {
  $Txt = str_replace('ABCDEFGHIJKLMNOPQRSTUVWXYZ','abc',$Txt);
}


?>
By: mgb
Date: 2007-12-27
Time: 10:32

Re: script=;subtp problem revisteted (Sorry for double-posting)

Output:
value before={ABCDEFGHIJKLMNOPQRSTUVWXYZ} <br>
value after={abc} <br>
serialize={s:26:"abc";} <br>


Reproduced with cli and cgi-fcgi on:
red:~> uname -a
FreeBSD red 5.4-RELEASE-p6 FreeBSD 5.4-RELEASE-p6 #1: Sat Jul 30 20:32:56 CEST 2005     operator@red:/usr/ports/obj/usr/src/sys/RED  i386

red:~> php -v
PHP 5.2.3 with Suhosin-Patch 0.9.6.2 (cli) (built: Sep 18 2007 14:30:46)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies

red:~> php -m
[PHP Modules]
curl
date
libxml
mysql
pcre
Reflection
session
sockets
standard
xml

[Zend Modules]

white:~% uname -a
Linux white 2.6.23-gentoo-r3 #3 SMP Sat Dec 15 17:19:04 CET 2007 i686 Intel(R) Core(TM)2 CPU 6320 @ 1.86GHz GenuineIntel GNU/Linux

white:~% php -v
PHP 5.2.5-pl1-gentoo with Suhosin-Patch 0.9.6.2 (cli) (built: Dec 12 2007 19:30:52)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
    with Suhosin v0.9.18, Copyright (c) 2002-2006, by Hardened-PHP Project

white:~% php -m
[PHP Modules]
date
dba
dom
gd
iconv
libxml
mbstring
mcrypt
ncurses
openssl
pcre
readline
Reflection
session
SPL
standard
suhosin
xml
zlib

[Zend Modules]
Suhosin
By: TomH
Date: 2007-12-27
Time: 19:14

Re: script=;subtp problem revisteted (Sorry for double-posting)

Hi Skrol29
Server1... Linux 2.6.21.5-ts.grh.mh.i386 / php 5.2.4 server api CGI /
Result...
value before={ABCDEFGHIJKLMNOPQRSTUVWXYZ}
value after={abc}
serialize={s:26:"abc";}

Server2... WinXP SP2 - XAMMP/ Apache/2.2.6 (Win32) PHP/5.2.4
Result...
value before={ABCDEFGHIJKLMNOPQRSTUVWXYZ}
value after={abc}
serialize={s:26:"abc";}

Thanks for TBS,
TomH
By: Skrol29
Date: 2007-12-29
Time: 01:42

Re: script=;subtp problem revisteted (Sorry for double-posting)

idem on PHP 5.2.5
By: Skrol29
Date: 2007-12-29
Time: 13:07

Re: script=;subtp problem revisteted (Sorry for double-posting)

You can follow the bug here:

http://bugs.php.net/43700
By: mgb
Date: 2008-01-02
Time: 08:47

Re: script=;subtp problem revisteted (Sorry for double-posting)

Hi Skrol29,
Sorry for my late reply, I just got back from vacation :)
I have been looking at the code you submitted to bug.php.net

And as far as I can see its not a reproduction of the error in tbs?

if you add a echo $Txt after f_Action1($Txt)
you will get:

value before={ABCDEFGHIJKLMNOPQRSTUVWXYZ} <br>
value after={ABCDEFGHIJKLMNOPQRSTUVWXYZ} <br>
serialize={s:26:"ABCDEFGHIJKLMNOPQRSTUVWXYZ";} <br>

and when f_Action2 is run  you actually only replace the
two last 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' parts.

Maybe its just me, but this is a correct action from php?
By: mgb
Date: 2008-01-02
Time: 10:03

Re: script=;subtp problem revisteted (Sorry for double-posting)

Hi again,
I have narrowed it down a bit. Please look at the following examples
tpl:
[onshow;script=[var.__navbarscript;noerr];subtpl;total=2667;noerr]

php:
if(isset($CurrPrm['total'])) {
echo '|'.$CurrPrm['total'].'|';
  $i = 0;
  while(($Chr = $CurrPrm['total'][$i])) {
    echo '|'.$Chr.'|';
    $i++;
  }
echo '|'.serialize($CurrPrm['total']).'|';
}

result:
|2667||2||6||6||7||s:4:"2667";|

and the second:
tpl:
[onshow;script=[var.__navbarscript;noerr];subtpl;total=[var.total_gals;noerr;ifempty=0];noerr]

php:
//the same

result:
|2667||[||v||a||r||.||t||o||t||a||l||_||g||a||l||s||;||n||o||e||r||r||;||i||f||e||m||p||t||y||=||s:32:"2667";|
The problem only occurs once you have a block in a block [ [] ]
I believe TomH also reproduced this in the last thread.

Still this is some kind of php reference bug. I have tried looking in
the tbs class and found that on line 2902 the function
tbs_Locator_PrmCompute is setting the param to [var.total_gals .... ]
but I cant find the functiont that turns this into 2667.
I have been looking at meth_Merge_AutoVar but I can't figure out how it
works and when its called on params?
So after an hour of browsing code I am still as puzzled :)
By: Skrol29
Date: 2008-01-04
Time: 12:44

Re: script=;subtp problem revisteted (Sorry for double-posting)

Hi Mgb,

I thing the TBS bug you've described is the same bug I've submitted but encapsulated into many more functions and variables.

Like you, I've found that :
- the bug occurs only when using parameter "subtpl" (with parameter "script"),
- the bug occurs only when there is an encapsulated TBS field in one of the parameter.

In order to point out what it going wrong with you first description of the bug, I've also tracked the content of the $CurrPrm['total'] variable during the merging process.

What I've found is this :

- The content of $CurrPrm['total'] changes just when ob_start() is called.
(function meth_Misc_ChangeMode(), line 2171, TBS 3.2.0 for PHP 5). At this point, the content of the variable is referenced by $Loc->PrmLst['total'] , and you can test yourself that its content changes suddently.

- In line 671, if you turn the code meth_Merge_AutoAny('var') as a  comment, or if you put trackers in it, you'll see that this line is not called when expected, if fact is is called when ob_start() is called.
I can sum up the process tree like this:
->Show()
  ->meth_Merge_AutoAny('onshow') // search for [onshow] tags
    ->meth_Locator_Replace() // merge the [onshow] field
      ->meth_Misc_ChangeMode() // turn into subtemplate mode
        ob_start() // BUG: contents changes here
  ->meth_Merge_AutoAny('var') // not called when expected

And thats the configuration that the bug I've submitted tp php.net can reproduce.
By: mgb
Date: 2008-01-04
Time: 13:27

Re: script=;subtp problem revisteted (Sorry for double-posting)

Hi Skrol29,
Thanks for the layout, I will try looking at it over the weekend.
I think you misunderstood me regarding the code that should reproduce the error.
I think it does not.
Try this modification:
$Txt = '';
echo 'before f_Action1'."\n";
f_Action1($Txt);
echo "\n".'before f_Action2'."\n";
echo $Txt."\n";
f_Action2($Txt);
echo 'after f_Action2'."\n";
echo $Txt."\n";

function f_Action1(&$Txt) {
  echo '  in f_Action1'."\n";
  $z = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  echo '    before obstart '.serialize($z)."\n";
  ob_start();
  echo '      inside ob_start '.serialize($z)."\n";
  $Txt = ob_get_contents();
  echo '      after ob_get_content '.serialize($z)."\n";
  ob_end_clean();
  echo '    after ob_end_clean '.serialize($z)."\n";
}

function f_Action2(&$Txt) {                                                             
  echo '  in f_Action2'."\n";
  $Txt = &str_replace('ABCDEFGHIJKLMNOPQRSTUVWXYZ',123,$Txt);
}

it will output
before f_Action1
  in f_Action1
    before obstart s:26:"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    after ob_end_clean s:26:"ABCDEFGHIJKLMNOPQRSTUVWXYZ";

before f_Action2
      inside ob_start s:26:"ABCDEFGHIJKLMNOPQRSTUVWXYZ";

  in f_Action2
after f_Action2
      inside ob_start s:26:"123";

In this result all is ok. The only thing f_Action2 does is replacing "ABCDEFGHIJKLMNOPQRSTUVWXYZ" with 123 after f_Action1 has finished.
Am I wrong?
By: Skrol29
Date: 2008-01-04
Time: 14:02

Re: script=;subtp problem revisteted (Sorry for double-posting)

> In this result all is ok.

inside ob_start s:26:"123";
is not ok.
And I bet that if you do your inside reading char by char you will found a long string just like you had with $CurrPrm['total'].

> The only thing f_Action2 does is replacing "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
> with 123 after f_Action1 has finished.

It seems that in your new snippet, f_Action2() has been called twice. Once at the bad time and once at the good time.
By: mgb
Date: 2008-01-04
Time: 16:15

Re: script=;subtp problem revisteted (Sorry for double-posting)

Hi Skrol29,
I took the chance and started playing with the tbs class.
I made this little change and voila (French, I think :))

it worked!

2166c2166
<               $Loc->SaveRender = $this->Render;
---
>               $Loc->SaveRender = $this->Render; $this->Render = 0;
2171c2171
<               ob_start(); // Start buffuring output
---
> //            ob_start(); // Start buffuring output
2173c2173,2174
<               // Restore contents configuration
---
>     // Restore contents configuration
>     $CurrVal =& $this->Source;
2177,2178c2178,2179
<               $CurrVal = ob_get_contents();
<               ob_end_clean();
---
> //            $CurrVal = ob_get_contents();
> //            ob_end_clean();

output before hack:
sakuraba:~/test% php test.php
global test:       2667
global serialized: i:2667;
script test:    2667
script serialized:      s:38:"2667";

output after hack:
script test:    2667
script serialized:      s:38:"2667";

global test:       2667
global serialized: i:2667
its the last line we are interested in.

Of course I am not sure this wont break a million other things in tbs :D
And I also know 'we' (meaning you) already knew the problem lay in the ob_* functions.
But could this be a valid fix (or begining of one anyway)?.

On a half side note: is there a way to have 'noerr' as default. I have
seen the 'public $NoErr = false;' but as far as I can tell this is not
reused any other place futher down in the code?

/mgb

By: mgb
Date: 2008-01-04
Time: 16:25

Re: script=;subtp problem revisteted (Sorry for double-posting)

btw, I know this also affects onformat wich is why this is not a perfect solution.
By: Skrol29
Date: 2008-01-04
Time: 16:44

Re: script=;subtp problem revisteted (Sorry for double-posting)

Hello,

I'm sorry I don't understand what have change in your code.

You can make "noerr" as default using $TBS->NoErr = true;
By: mgb
Date: 2008-01-04
Time: 19:11

Re: script=;subtp problem revisteted (Sorry for double-posting)

I modified meth_Misc_ChangeMode
But I guess this wont work for onformat.
Also it will break backward compatibility, since you wont be able to use echo and print in subtpl anymore.

function meth_Misc_ChangeMode($Init,&$Loc,&$CurrVal) {
  if ($Init) {
    // Save contents configuration
    $Loc->SaveSrc =& $this->Source;
    $Loc->SaveRender = $this->Render; $this->Render = 0;
    $Loc->SaveMode = $this->_Mode;
    unset($this->Source); $this->Source = '';
    $this->Render = TBS_OUTPUT;
    $this->_Mode++; // Mode>0 means subtemplate mode
//    ob_start(); // Start buffuring output
  } else {
    // Restore contents configuration
    $CurrVal =& $this->Source;
    $this->Source =& $Loc->SaveSrc;
    $this->Render = $Loc->SaveRender;
    $this->_Mode = $Loc->SaveMode;
//    $CurrVal = ob_get_contents();
//    ob_end_clean();
  }
}
By: mgb
Date: 2008-01-08
Time: 09:37

Re: script=;subtp problem revisteted (Sorry for double-posting)

Hi Skrol29,
Sorry to bother you with this again :)
But I am still not convinced that the code, to reproduce the php bug, is valid.
Lets say you do this:
<snip>
$Txt = '';
f_Action1($Txt);
echo $Txt;                                                                              
f_Action2($Txt);
echo $Txt;
</snip>

The output would be:

Expected result:
----------------
value before={ABCDEFGHIJKLMNOPQRSTUVWXYZ}
value after={ABCDEFGHIJKLMNOPQRSTUVWXYZ}
serialize={s:26:"ABCDEFGHIJKLMNOPQRSTUVWXYZ";}

Actual result:
--------------
value before={ABCDEFGHIJKLMNOPQRSTUVWXYZ} <br>
value after={ABCDEFGHIJKLMNOPQRSTUVWXYZ} <br> *
serialize={s:26:"ABCDEFGHIJKLMNOPQRSTUVWXYZ";} <br> *
value after={abc} <br>
serialize={s:26:"abc";} <br>

Take a look at the 4th and 3th last line maked with (*).
That originates from the first  echo $Txt; which is done just before f_Action2($Txt);
Here the values are still ABCDEFGHIJKLMNOPQRSTUVWXYZ.
All f_Action2 does it to do a normal replace on Txt reference?

if you change f_Action1 to look like this:
function f_Action1(&$Txt) {
  $z = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  echo "value before={".$z."} <br>\r\n"
  $Txt = "value after={".$z."} <br>\r\n"; // Bug here : it is like Action2() has be
  $Txt .= "serialize={".serialize($z)."} <br>\r\n"; // Bug here : the serialization
}

The output will still be the same:
Expected result:
----------------
value before={ABCDEFGHIJKLMNOPQRSTUVWXYZ}
value after={ABCDEFGHIJKLMNOPQRSTUVWXYZ}
serialize={s:26:"ABCDEFGHIJKLMNOPQRSTUVWXYZ";}

Actual result:
--------------
value before={ABCDEFGHIJKLMNOPQRSTUVWXYZ} <br>
value after={ABCDEFGHIJKLMNOPQRSTUVWXYZ} <br> *
serialize={s:26:"ABCDEFGHIJKLMNOPQRSTUVWXYZ";} <br> *
value after={abc} <br>
serialize={s:26:"abc";} <br>

Sorry. But I just don't see how this example can reproduce the bug?
By: Skrol29
Date: 2008-01-09
Time: 14:59

Re: script=;subtp problem revisteted (Sorry for double-posting)

Hi Mgb,

I don't agree with your "Expected result" parts but this is just a detail.

You're right, my script has no bug and this is not the TBS problem.
(I have to cancel the bug post at php.net)

So I'm back on this damed TBS strange behavior...
By: mgb
Date: 2008-01-09
Time: 15:26

Re: script=;subtp problem revisteted (Sorry for double-posting)

I was wondering, are there anyone that has the posibility to test this on a php4 machine?
http://mgb.deter.dk/tbs.tar.bz2
I know that referecing variables changed a lot from 4 to 5
and if you do try to change some of the =& to = in meth_Misc_ChangeMode it will give funny results.
not only slow the rendering down.

/mgb
By: Skrol29
Date: 2008-01-09
Time: 15:37

Re: script=;subtp problem revisteted (Sorry for double-posting)

Hello,

I have a PHP 4 configuration on my PC, but you are asking to test a binay file "script.php".

You suggestion to deactivate ob_start() in order to walkaround the bug is strange because isn't it equivalent to not using parameter "subtpl" ?
By: Skrol29
Date: 2008-01-09
Time: 16:11

Re: script=;subtp problem revisteted (Sorry for double-posting)

So, here I am, back on your first problem.

Consider the following test:
$sum_of_all = 29;

$TBS = new clsTinyButStrong;
$TBS->LoadTemplate('test.html');
$TBS->Show();

test.html:
([onshow;script=callie.php;subtpl;total=[var.sum_of_all]])

callie.php:
<?php
echo '{'.serialize($CurrPrm['total']).'}';
?>

Actual result:
({s:16:"29";})

What is going on ?

During the execution of subcript "callie.php", the value of $CurrPrm['total'] is "[var.sum_of_all]". This is because [onshow] fields are processed before [var] fields.
You can do any numeric operation on $CurrPrm['total'], it should always return zero because the content is not a string of a numeric representation.

When "callie.php" is ending, the buffer for output redirection is containing "{s:16:"[var.sum_of_all]";}". Which is a correct contents.
This content is inserted into the main template, and then its [var] field is merged. The, the result is ({s:16:"29";}) which is correct too.

Note:Embedded [var] fields are merged immediately only for few parameters: file , script , subtpl , if , then , else , when. In your case is is embedded into a custom parameter "total".
By: mgb
Date: 2008-01-09
Time: 16:16

Re: script=;subtp problem revisteted (Sorry for double-posting)

yes, I accidentally uploaded a broken tar the one that is there now is the real one.
script.php was actually a broken copy of tbs.tar.bz2 :)

Yeah I was a bit to quick on the tricker with thinking I had it fixed :)
Obviously I didn't :D

About php4 I was wondering if it had used to work the an older version of php
as I know that php reference handling has changed over these two version.

Basically I was just curious :)
By: mgb
Date: 2008-01-09
Time: 16:34

Re: script=;subtp problem revisteted (Sorry for double-posting)

Aha :)
So actually there is only one bug/problem is ... ME :)

Its a bit sad though, that I am not able to 'give' subtpl scripts parameters in this way.
It would be nice if the subscript didn't have to worry about global variables and that the calling script didn't have to have certain global variables set.

Could the possibility of 'giving' sub scripts parameters in this fashion be a feature for an upcoming tbs release? Or would the penalty, performance vice, be to hard?
By: mgb
Date: 2008-01-09
Time: 16:35

Re: script=;subtp problem revisteted (Sorry for double-posting)

And also, Skrol29, Thanks for being so patient with me.
I can be kind of a hard-head sometimes :)
I really appreciate all the work you put into tbs.

/Morten
By: Skrol29
Date: 2008-01-09
Time: 16:45

Re: script=;subtp problem revisteted (Sorry for double-posting)

>Its a bit sad though, that I am not able to 'give' subtpl scripts parameters in this way.

You cannot give subtpl parameters which are automatically merged.
But if you know this parameter is a global variable you can do:
Template: ([onshow;script=callie.php;subtpl;total=sum_of_all])
Subscript: $total = $GLOBAL[$CurrPrm['total']];

Another way is to force a TBS merge on variable that you want. A small code in your subscript can do that.