Issues

ZF-7586: Zend_Json_Decoder emits fatal error when decoding JSON string with empty key

Description

If I asked Zend JSON to decode a response as an object that includes a structure with a key that's an impty string, it causes a fatal error:

Cannot access empty property in Zend/Json/Decoder.php on line 239

In contrast, the PHP 5.2 built-in json_decode() will handle this gracefully and assign the key 'empty'.

I think this can be handled easily by the following change:

Index: Json/Decoder.php
===================================================================
--- Json/Decoder.php (revision 5082)
+++ Json/Decoder.php (working copy)
@@ -236,6 +236,10 @@
                 // Create new StdClass and populate with $members
                 $result = new StdClass();
                 foreach ($members as $key => $value) {
+                    if ($key === '') {
+                      // Mimic PHP 5.2 behavior
+                      $key = '_empty_';
+                    }
                     $result->$key = $value;
                 }
                 break;

There should be some sort of check, at least, here to insure that the $key is valid.

see also: http://drupal.org/node/465528

Comments

Could not reproduce against trunk with this unit test:


Index: tests/Zend/JsonTest.php
===================================================================
--- tests/Zend/JsonTest.php (revision 24547)
+++ tests/Zend/JsonTest.php (working copy)
@@ -887,6 +887,17 @@
         $json = Zend_Json::encode($array);
         $this->assertEquals($expected, $json);
     }
+    
+    /**
+     * @group ZF-7586
+     */
+    public function testWillDecodeStructureWithEmptyKeyToObjectProperly()
+    {
+        $json = '{"":"test"}';
+        $object = Zend_Json::decode($json, Zend_Json::TYPE_OBJECT);
+        $this->assertTrue(isset($object->_empty_));
+        $this->assertEquals('test', $object->_empty_);
+    }
 
 }
 

Prematurely closed due to omission from unit test above.

This unit test reproduces the issue:


Index: tests/Zend/JsonTest.php
===================================================================
--- tests/Zend/JsonTest.php (revision 24547)
+++ tests/Zend/JsonTest.php (working copy)
@@ -887,6 +887,19 @@
         $json = Zend_Json::encode($array);
         $this->assertEquals($expected, $json);
     }
+    
+    /**
+     * @group ZF-7586
+     */
+    public function testWillDecodeStructureWithEmptyKeyToObjectProperly()
+    {
+        Zend_Json::$useBuiltinEncoderDecoder = true;
+        
+        $json = '{"":"test"}';
+        $object = Zend_Json::decode($json, Zend_Json::TYPE_OBJECT);
+        $this->assertTrue(isset($object->_empty_));
+        $this->assertEquals('test', $object->_empty_);
+    }
 
 }

Attached patch file with reproducing unit test + fix.

Does changing this behavior of {{Zend_Json}} at this stage in ZFv1's lifecycle constitute a BC break?

Fixed in trunk (1.12.0): r24799 ZF2 Pull Request: https://github.com/zendframework/zf2/pull/1217