From ab0f4f07ad55a945f6a748af2526b48c01b5d138 Mon Sep 17 00:00:00 2001 From: Adam Lundrigan Date: Sun, 28 Aug 2011 13:24:04 -0230 Subject: [PATCH] [hotfix/ZF-10185] Update Zend\Json\Json::prettyPrint to properly distinguish between array/object notation in string literals and actual encoded arrays/objects --- library/Zend/Json/Json.php | 16 ++++++++++---- tests/Zend/Json/JsonTest.php | 42 ++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/library/Zend/Json/Json.php b/library/Zend/Json/Json.php index 5a4c7b11b8c..6e2a7ae1003 100644 --- a/library/Zend/Json/Json.php +++ b/library/Zend/Json/Json.php @@ -366,24 +366,32 @@ public static function prettyPrint($json, $options = array()) $ind = $options['indent']; } + $inLiteral = false; foreach($tokens as $token) { if($token == "") continue; $prefix = str_repeat($ind, $indent); - if($token == "{" || $token == "[") { + if(!$inLiteral && ($token == "{" || $token == "[")) { $indent++; if($result != "" && $result[strlen($result)-1] == "\n") { $result .= $prefix; } $result .= "$token\n"; - } else if($token == "}" || $token == "]") { + } else if(!$inLiteral && ($token == "}" || $token == "]")) { $indent--; $prefix = str_repeat($ind, $indent); $result .= "\n$prefix$token"; - } else if($token == ",") { + } else if(!$inLiteral && $token == ",") { $result .= "$token\n"; } else { - $result .= $prefix.$token; + $result .= ($inLiteral ? '' : $prefix) . $token; + + // Count # of unescaped double-quotes in token, subtract # of + // escaped double-quotes and if the result is odd then we are + // inside a string literal + if ((substr_count($token, "\"")-substr_count($token, "\\\"")) % 2 != 0) { + $inLiteral = !$inLiteral; + } } } return $result; diff --git a/tests/Zend/Json/JsonTest.php b/tests/Zend/Json/JsonTest.php index 4670a986f67..0967a1b16a1 100644 --- a/tests/Zend/Json/JsonTest.php +++ b/tests/Zend/Json/JsonTest.php @@ -772,6 +772,48 @@ public function testDefaultTypeObject() $this->assertInstanceOf('stdClass', Json\Decoder::decode('{"var":"value"}')); } + /** + * @group ZF-10185 + */ + public function testJsonPrettyPrintWorksWithArrayNotationInStringLiteral() + { + $o = new \stdClass(); + $o->test = 1; + $o->faz = 'fubar'; + + // The escaped double-quote in item 'stringwithjsonchars' ensures that + // escaped double-quotes don't throw off prettyPrint's string literal detection + $test = array( + 'simple'=>'simple test string', + 'stringwithjsonchars'=>'\"[1,2]', + 'complex'=>array( + 'foo'=>'bar', + 'far'=>'boo', + 'faz'=>array( + 'obj'=>$o + ) + ) + ); + $pretty = Json\Json::prettyPrint(Json\Json::encode($test), array("indent" => " ")); + $expected = <<assertSame($expected, $pretty); + } + } /**