6.0.0-git
2019-04-25

[#5604] ListMessages endless loop
Summary ListMessages endless loop
Queue DIMP
Queue Version 1.0-ALPHA
Type Bug
State Resolved
Priority 1. Low
Owners slusarz (at) horde (dot) org
Requester vokac (at) kmlinux (dot) fjfi (dot) cvut (dot) cz
Created 2007-08-05 (4281 days ago)
Due
Updated 2007-08-08 (4278 days ago)
Assigned 2007-08-05 (4281 days ago)
Resolved 2007-08-08 (4278 days ago)
Milestone
Patch No

History
2007-08-08 05:36:19 Michael Slusarz Comment #12
Assigned to Michael Slusarz
State ⇒ Resolved
Reply to this comment
You live, you learn.  Turns out you can't have numeric properties in 
an object - or more accurately, your property can't begin with an 
integer (i.e. you can't have $obj->1 or $obj->1foo).  And it turns out 
that encoding $msglist as a regular array does return the correct 
"{'integer':integer,'integer2':integer2}" form.  I know for a fact 
this did not work like this before - but I think the difference now is 
that we build $msglist ourselves now earlier in the function - and 
since we are creating the array directly by doing $msglist[integer] 
calls, PHP is interpreting these indices as string indices.  I can 
almost guarantee you before we were building via $msglist[], or maybe 
an array_keys() or array_values() call, or something similar that 
resulting in the array being created with indexed integers rather than 
string indices.
2007-08-08 03:59:28 vokac (at) kmlinux (dot) fjfi (dot) cvut (dot) cz Comment #11 Reply to this comment
To me, this indicates that the version of PHP that ships with CentOS
is broken.  If these functions are not doing what they are supposed
to be doing, there's not much we can do about that in our code.  And
get_object_vars() has been around since PHP 4 so this shouldn't be a
code stability/maturity issue.
Well I made tests with script I send ealier with other four different 
versions of PHP and the result for 5.x versions are always same (bad), 
version 4.x works:





Official windows version PHP 4.4.7 - get_object_vars works:



c:\Documents and Settings\vokac\Desktop\php-4.4.7-Win32>php test.php

X-Powered-By: PHP/4.4.7

Content-type: text/html



get_object_vars:

   >> 1: 1

   >> 2: 2

iterator(?):

   >> 1: 1

   >> 2: 2







Official windows version PHP 5.2.3 - get_object_vars doesnt work:



c:\Documents and Settings\vokac.ATLASDELL\Desktop\php-5.2.3-Win32>php 
test2.php

get_object_vars:

iterator(?):

   >> 1: 1

   >> 2: 2







Official PHP 4.3.9 from RHEL4/CentOS4, get_object_vars works:



[root@mailgw1 html]# php test2.php

Content-type: text/html

X-Powered-By: PHP/4.3.9



get_object_vars:

   >> 1: 1

   >> 2: 2

iterator(?):

   >> 1: 1

   >> 2: 2







PHP 5.1.6 compiled from official sources (without any patch) - 
get_object_vars doesnt work, iterator doesnt work:



[vokac@kmlinux cgi]$ ./php test2.php

X-Powered-By: PHP/5.1.6

Content-type: text/html



get_object_vars:

iterator(?):







Did you try the testing code in you PHP 5.x version? Does it work 
correctly? I really don't know what I should do to force 
get_object_vars work in PHP 5.x





<?php

$a = array('1' => 1, '2' => 2);

$b = (object)$a;

$c = get_object_vars($b);

echo "get_object_vars:\n";

foreach($c as $name=>$value) {

   echo "  $name: $value\n";

}

echo "iterator(?):\n";

foreach($b as $name=>$value) {

   echo "  $name: $value\n";

}

?>
2007-08-08 03:13:47 vokac (at) kmlinux (dot) fjfi (dot) cvut (dot) cz Comment #10 Reply to this comment

[Show Quoted Text - 13 lines]
Well, but if you look at your implementation of JSON serialization, 
you handle asociative arrays differently than normal arrays. See also 
comment in lib/Horde/Serialize/JSON.php:133



             /* As per JSON spec if any array key is not an integer we

              * must treat the the whole array as an object. We also

              * try to catch a sparsely populated associative array

              * with numeric keys here because some JS engines will

              * create an array with empty indexes up to max_index

              * which can cause memory issues and because the keys,

              * which may be relevant, will be remapped otherwise.

              *

              * As per the ECMA and JSON specification an object may

              * have any string as a property. Unfortunately due to a

              * hole in the ECMA specification if the key is a ECMA

              * reserved word or starts with a digit the parameter is

              * only accessible using ECMAScript's bracket notation. */



According me it means, that casting associative array with string keys 
to object is not required (and with cast to object it doesn't work on 
probably somehow broken PHP in RHEL5/CentOS5 - I'll try to figure out 
the reason why get_object_vars doesn't work on this system, but right 
now I tested PHP 5.1.6 compiled from sources and it doesn't work 
either).
2007-08-07 20:26:39 Michael Slusarz Comment #9
Priority ⇒ 1. Low
Reply to this comment
It means that you can't use get_object_vars to access array content
in lib/Horde/Serialize/JSON.php:161 (on both systems) and with
iterator you can access array content only with PHP 5.2.2. If you
typecast object back to array, you can access array content also with
PHP 5.1.6 (CentOS5).
To me, this indicates that the version of PHP that ships with CentOS 
is broken.  If these functions are not doing what they are supposed to 
be doing, there's not much we can do about that in our code.  And 
get_object_vars() has been around since PHP 4 so this shouldn't be a 
code stability/maturity issue.


2007-08-07 20:06:00 Michael Slusarz Comment #8 Reply to this comment
We need to cast it to an object, otherwise the JSON would probably
look like this:

[1, 2, 3]

instead of:

{'1': 1, '2': 2, '3': 3}
This is precisely the reason.  In javascript land, we are accessing 
the array via the message index (our message indices just happen to 
look like integers), which is a string value, rather than an integer 
value because the latter would indicate the position in the JS array.
2007-08-06 07:47:29 vokac (at) kmlinux (dot) fjfi (dot) cvut (dot) cz Comment #7 Reply to this comment
<?php

$a = array('1' => 1, '2' => 2);

$b = (object)$a;

$c = get_object_vars($b);

echo "get_object_vars:\n";

foreach($c as $name=>$value) {

   echo "  $name: $value\n";

}

echo "iterator(?):\n";

foreach($b as $name=>$value) {

   echo "  $name: $value\n";

}

?>





Output on CentOS5 (PHP 5.1.6):

get_object_vars:

iterator(?):





Output on Fedora7 (PHP 5.2.2):

get_object_vars:

iterator(?):

   1: 1

   2: 2





It means that you can't use get_object_vars to access array content in 
lib/Horde/Serialize/JSON.php:161 (on both systems) and with iterator 
you can access array content only with PHP 5.2.2. If you typecast 
object back to array, you can access array content also with PHP 5.1.6 
(CentOS5).


2007-08-06 07:05:00 vokac (at) kmlinux (dot) fjfi (dot) cvut (dot) cz Comment #6 Reply to this comment
It seems that var_export dosn't work well on objects (it doesn't print 
all variables). I use print_r and you can see that typecast to 
(object) only change data type - the value is still same.





--- horde.log   2007-08-06 08:55:49.000000000 +0200

+++ horde.log.original  2007-08-06 08:56:49.000000000 +0200

@@ -55,7 +55,7 @@



          )



-    [msglist] => Array

+    [msglist] => stdClass Object

          (

              [1] => 1

              [2] => 2


2007-08-06 02:42:00 vokac (at) kmlinux (dot) fjfi (dot) cvut (dot) cz Comment #5 Reply to this comment

[Show Quoted Text - 13 lines]
On CentOS5 it returns:

object(stdClass)#1 (2) { [1]=>  int(1) [2]=>  int(2) } 
stdClass::__set_state(array( ))



On Fedora7 it returns:

<pre>

<b>object</b>(<i>stdClass</i>)[<i>1</i>]

   <small>int</small> <font color='#4e9a06'>1</font>

   <small>int</small> <font color='#4e9a06'>2</font>

</pre>stdClass::__set_state(array(

))



(btw: PHP on Fedora7 has json extension)


2007-08-06 02:26:22 Chuck Hagenbuch Comment #4 Reply to this comment

[Show Quoted Text - 15 lines]
That's weird; that actually indicates to me a PHP bug, that you're 
losing the values of the array when casting it to an object.



We need to cast it to an object, otherwise the JSON would probably 
look like this:



[1, 2, 3]



instead of:



{'1': 1, '2': 2, '3': 3}



(which is important when it's 10048, 10051, 10046, in that order, and 
not just 1, 2, 3).



Can you make a short test script which is just:



<?php



var_dump((object)array('1' => 1, '2' => 2));

echo var_export((object)array('1' => 1, '2' => 2), true);





And run it on both versions? (interestingly, the var_export might just 
mangle it. The var_dump is okay in my case though. Looks like it might 
be a bug in our json encoder, except that it's weird that the effect 
of var_export is exactly what you see when using var_export on it ...)
2007-08-06 00:24:35 vokac (at) kmlinux (dot) fjfi (dot) cvut (dot) cz Comment #3 Reply to this comment
If that box does *NOT* have a json extension, then this is a bug in
Horde_Serialize_JSON and we should add a unit test for it - if this
is the case it'd be helpful if you could include a var_export of the
$result object so we can toss it into the test quickly.
Yes, PHP on CentOS5 doesn't have json extension. If I use var_export 
on original code, I get this output:



     'msglist' =>

   stdClass::__set_state(array(

   )),



but when I remove typecast to "object", I get different output:



     'msglist' =>

   array (

     1 => 1,

     2 => 2,

     3 => 3,

   ),


2007-08-05 23:06:39 Chuck Hagenbuch Comment #2
State ⇒ Feedback
Reply to this comment
That patch results in the same output for you in msglist, specifically 
that it's an associative array, not a numerically indexed array?



On the Centos/PHP 5.1.6 box that doesn't work, do you have a version 
of the PHP json extension? If you do, then this is likely a bug in 
that json version, and you should try disabling the json extension 
that you have (it was mainstreamed in PHP 5.2, so that version should 
work well).



If that box does *NOT* have a json extension, then this is a bug in 
Horde_Serialize_JSON and we should add a unit test for it - if this is 
the case it'd be helpful if you could include a var_export of the 
$result object so we can toss it into the test quickly.
2007-08-05 22:25:59 vokac (at) kmlinux (dot) fjfi (dot) cvut (dot) cz Comment #1
Type ⇒ Bug
State ⇒ Unconfirmed
Priority ⇒ 3. High
Summary ⇒ ListMessages endless loop
Queue ⇒ DIMP
Reply to this comment
Selecting mail folder results in endless loop of calling 
ListMessages.php. This problem seems to be probably related to 
specific version of PHP. It doesn't work on CentOS5 with PHP 5.1.6 
(see also 
http://lists.horde.org/archives/imp/Week-of-Mon-20070716/047606.html
but it works on Fedora 7 with PHP 5.2.2.





There is small difference in data that was returned by 
ListMessages.php on CentOS5 and Fedora7



CentOS5 (3 mails in INBOX):

/*-secure-{"response":{ ... ,"msglist":{}, ... },"msgs":[],"msgs_auto":true}*/

Fedora7 (3 mails in INBOX):

/*-secure-{"response":{ ... ,"msglist":{"1":1,"2":2,"3":3}, ... 
},"msgs":[],"msgs_auto":true}*/





To get rid of this problem on CentOS, I had to change following piece 
of code (I did not test it anywhere else, so I'm not sure if this 
patch works on all PHP versions).





--- dimp-h3-1.0-alpha/lib/Views/ListMessages.php.orig   2007-07-25 
07:57:30.000000000 +0200

+++ dimp-h3-1.0-alpha/lib/Views/ListMessages.php        2007-08-06 
00:11:50.000000000 +0200

@@ -182,7 +182,7 @@



          $result->lines = count($msglist);

          $result->msgdata = $msgs;

-        $result->msglist = (object)$msglist;

+        $result->msglist = $msglist;



          /* Mail-specific viewport information. */

          $md = new stdClass;


Saved Queries