Issues

ZF-9416: Zend_Json_Encoder creates invalid JSON for Zend_Json_Decoder

Issue Type: Bug Created: 2010-03-12T04:45:50.000+0000 Last Updated: 2010-06-18T11:19:33.000+0000 Status: Resolved Fix version(s): - 1.10.6 (22/Jun/10)

Reporter: Robert (rs) Assignee: Joel Clermont (jclermont) Tags: - Zend_Json

Related issues: Attachments: - req_types.zip

Description

This piece of JSON was created with Zend_Json_Encoder::encode

{"__className":"fgSDK_Types_TTrip","IDuser":1,"Smoker":"flex","NumberPlate":"WI-EN 89","Places":2,"Contactlandline":"0221 54899","Contactmobile":"0175 54899","Description":"ich fahre nach k\u00f6ln","ClientIP":"192.168.1.20","Triptype":"offer","Routings":{"__className":"fgSDK_Types_TRoutingCollection",0:{"__className":"fgSDK_Types_TRouting","Origin":{"__className":"fgSDK_Types_TPlace","Address":"K\u00f6ln, Deutschland","Accuracy":4,"CountryCode":"DE","CountryName":"Deutschland","Longitude":6.9599115,"Latitude":50.9406645,"Placetype":"geo","LatLonBox":{"__className":"fgSDK_Types_TLatLonBox","North":51.0530233,"South":50.8280335,"East":7.2160303,"West":6.7037927,"Destination":{"__className":"fgSDK_Types_TPlace","Address":"Hamburg, Deutschland","Accuracy":4,"CountryCode":"DE","CountryName":"Deutschland","Longitude":9.9921962,"Latitude":53.5534074,"Placetype":"geo","LatLonBox":{"__className":"fgSDK_Types_TLatLonBox","North":53.6593331,"South":53.4472158,"East":10.248315,"West":9.7360774,"RoutingIndex":-1}

During Decoding using Zend_Json_Decoder::decode this exception is thrown:

Message: Missing key in object encoding: {"__className":"fgSDK_Types_TTrip","IDuser":1,"Smoker":"flex","NumberPlate":"WI-EN 89","Places":2,"Contactlandline":"0221 54899","Contactmobile":"0175 54899","Description":"ich fahre nach köln","ClientIP":"192.168.1.20","Triptype":"offer","Routings":{"__className":"fgSDK_Types_TRoutingCollection",0:{"__className":"fgSDK_Types_TRouting","Origin":{"__className":"fgSDK_Types_TPlace","Address":"Köln, Deutschland","Accuracy":4,"CountryCode":"DE","CountryName":"Deutschland","Longitude":6.9599115,"Latitude":50.9406645,"Placetype":"geo","LatLonBox":{"__className":"fgSDK_Types_TLatLonBox","North":51.0530233,"South":50.8280335,"East":7.2160303,"West":6.7037927,"Destination":{"__className":"fgSDK_Types_TPlace","Address":"Hamburg, Deutschland","Accuracy":4,"CountryCode":"DE","CountryName":"Deutschland","Longitude":9.9921962,"Latitude":53.5534074,"Placetype":"geo","LatLonBox":{"__className":"fgSDK_Types_TLatLonBox","North":53.6593331,"South":53.4472158,"East":10.248315,"West":9.7360774,"RoutingIndex":-1} Stack trace:

0 D:\server\lib\zend1.10\Zend\Json\Decoder.php(174): Zend_Json_Decoder->_decodeObject()

1 D:\server\lib\zend1.10\Zend\Json\Decoder.php(219): Zend_Json_Decoder->_decodeValue()

2 D:\server\lib\zend1.10\Zend\Json\Decoder.php(174): Zend_Json_Decoder->_decodeObject()

3 D:\server\lib\zend1.10\Zend\Json\Decoder.php(156): Zend_Json_Decoder->_decodeValue()

4 D:\dev\web[REMOVED]\service.[REMOVED]\trunk\application\controllers\TripController.php(38): Zend_Json_Decoder::decode('{"__className":...')

5 D:\server\lib\zend1.10\Zend\Controller\Action.php(513): TripController->putAction()

6 D:\server\lib\zend1.10\Zend\Controller\Dispatcher\Standard.php(289): Zend_Controller_Action->dispatch('putAction')

7 D:\server\lib\zend1.10\Zend\Controller\Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))

8 D:\server\lib\zend1.10\Zend\Application\Bootstrap\Bootstrap.php(97): Zend_Controller_Front->dispatch()

9 D:\server\lib\zend1.10\Zend\Application.php(366): Zend_Application_Bootstrap_Bootstrap->run()

10 D:\dev\web[REMOVED]\service.[REMOVED]\trunk\public\index.php(76): Zend_Application->run()

11 {main}

Comments

Posted by Ben Scholzen (dasprid) on 2010-03-12T04:47:55.000+0000

Could you please provide the source data (array/object) for debugging?

Posted by Robert (rs) on 2010-03-12T05:21:20.000+0000

Please see the attached files.

You need to extract the ZIP file (required types)

in the zend.php you can see the object creation and structure.

Do you need anything else?

br robert

Posted by Robert (rs) on 2010-03-13T03:45:15.000+0000

Hi again,

sorry but its the first issue which I'm reported here.

What are the next steps? Is there a quick FIX available?

Can sombody here help in a short term?

br robert

Posted by Matthew Weier O'Phinney (matthew) on 2010-03-13T08:46:14.000+0000

Fixes to issues are prioritized by severity; that said, they're also going to occur based on availability of the contributors/maintainers of the components in question. The easier it is for a contributor to reproduce the issue, the easier it will be for them to work on it.

Is there any chance you can simplify the reproduce case further?

Posted by Robert (rs) on 2010-03-13T10:49:30.000+0000

I attached already this 2 Files, including only a few files to reproduce the issue. It should be very very easy to reproduce and debug it.

For my client SOA architecture this functionality is key.

Is there a timeframe which I can communicate anyhow?

br

Posted by Núria Aloy (nuqqsa) on 2010-04-14T15:04:23.000+0000

This bug is related to the fact that one of the classes is an instance of Iterator. In that case the encoder iterates the object itself instead of its variables to produce the JSON string.

It can be reproduced in the following scenarios:

<pre class="highlight">
class A implements Iterator {
    
    protected $_stack;
    
    public function __construct(array $array)
    {
        $this->_stack = $array;
    }
    
    public function rewind() {
        reset($this->_stack);
    }

    public function current() {
        return current($this->_stack);
    }

    public function key() {
        return key($this->_stack);
    }

    public function next() {
        return next($this->_stack);
    }

    public function valid() {
        return $this->current() !== false;
    }
}

$a = new A(array("foo"));
$encoded = Zend_Json_Encoder::encode($a);
$decoded = Zend_Json_Decoder::decode($encoded);
// Exception 'Zend_Json_Exception' with message 'Missing key in object encoding: {"__className":"A",0:"foo"}'



<pre class="highlight">
class B extends ArrayIterator
{
    
}
$b = new B(array("foo"));
$encoded = Zend_Json_Encoder::encode($b);
$decoded = Zend_Json_Decoder::decode($encoded);
// Exception 'Zend_Json_Exception' with message 'Missing key in object encoding: {"__className":"B",0:"foo"}'

Posted by Joel Clermont (jclermont) on 2010-05-20T15:15:23.000+0000

ZF-9416.patch includes a test that demonstrates this bug. The problem relates to the fact that ArrayIterator gets encoded as an object in JSON, which requires a string key for each value. However, when an array without keys is encoded it is an array in JSON, which does not have keys. I'm not sure what the proper behavior should be. Do we convert numeric keys to strings and preserve it as an object? Do we embed an array within the JSON object and follow the same rules for encoding arrays?

Posted by Joel Clermont (jclermont) on 2010-05-20T15:23:04.000+0000

I think the proper behavior is demonstrated by json_encode:

<pre class="highlight">
$iteratorA = new ArrayIterator(array('foo'));
$encoded = json_encode($iteratorA);
var_dump($encoded);

This produces:

<pre class="highlight">
string(11) "{"0":"foo"}" 

I am going to follow this behavior in Zend_Json::encode and add the numeric keys as strings for safety.

Posted by Joel Clermont (jclermont) on 2010-05-20T17:14:04.000+0000

In the sample code, it is calling Json_Encoder and Json_Decoder directly. A better approach is to use Json::encode and Json::decode. This way, if you have json support in PHP it will use the native functions json_encode and json_decode. Not only is it faster, but this bug does not occur. The bug only exists in the internal class Json_Encoder (which I will soon fix).

Posted by Joel Clermont (jclermont) on 2010-05-20T17:56:54.000+0000

ZF-9416-2.patch fixes the bug and includes a better unit test. I fixed the bug by using the internal _encodeString function for keys within an object, since JSON requires that object keys always be strings. This handles the encoding of numeric keys in the same way as the native json_encode feature now. Unit test now passes. Should be ready to commit.

Posted by Joel Clermont (jclermont) on 2010-06-04T19:14:14.000+0000

Unit test written to demonstrate the problem and prove that the patch fixes it. Please use the ZF-9416-2.patch file.

Posted by Ralph Schindler (ralph) on 2010-06-18T11:18:47.000+0000

Was not resolved in code (yet).

Posted by Ralph Schindler (ralph) on 2010-06-18T11:19:33.000+0000

Resolved in r22452 in trunk and in r22453 in release branch 1.10 with patch "-2" from above.

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts