From 74873cfdc6060be45dbbdaf73e428e54694ae828 Mon Sep 17 00:00:00 2001 From: Adam Lundrigan Date: Fri, 26 Aug 2011 20:55:33 -0230 Subject: [PATCH 1/2] Integrated unit tests from ZF-11385 which prove that recursion count problem introduced (and subsequently fixed) in ZF-3257 --- test/JsonXmlTest.php | 74 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/test/JsonXmlTest.php b/test/JsonXmlTest.php index b5c10bceb..8571c0cee 100644 --- a/test/JsonXmlTest.php +++ b/test/JsonXmlTest.php @@ -545,6 +545,80 @@ public function testUsingXML8() { } + /** + * @group ZF-11385 + * @expectedException Zend\Json\Exception\RecursionException + * @dataProvider providerNestingDepthIsHandledProperly + */ + public function testNestingDepthIsHandledProperlyWhenNestingDepthExceedsMaximum($xmlStringContents) + { + Json\Json::$maxRecursionDepthAllowed = 1; + Json\Json::fromXml($xmlStringContents, true); + } + + /** + * @group ZF-11385 + * @dataProvider providerNestingDepthIsHandledProperly + */ + public function testNestingDepthIsHandledProperlyWhenNestingDepthDoesNotExceedMaximum($xmlStringContents) + { + try { + Json\Json::$maxRecursionDepthAllowed = 25; + $jsonString = Json\Json::fromXml($xmlStringContents, true); + $jsonArray = Json\Json::decode($jsonString, Json\Json::TYPE_ARRAY); + $this->assertNotNull($jsonArray, "JSON decode result is NULL"); + $this->assertSame('A', $jsonArray['response']['message_type']['defaults']['close_rules']['after_responses']); + } catch ( Zend\Json\Exception\RecursionException $ex ) { + $this->fail('Zend_Json::fromXml does not implement recursion check properly'); + } + } + + /** + * XML document provider for ZF-11385 tests + * @return array + */ + public static function providerNestingDepthIsHandledProperly() + { + $xmlStringContents = << + success + 200 OK + + A + B + C + D + E + F + G + H + A + B + C + D + E + A + B + C + D + E + + + A + + B + C + A + B + C + D + + + 0.0790269374847 + +EOT; + return array(array($xmlStringContents)); + } } From 469e2592fcad8217d911b6a502c826fb51979347 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 30 Aug 2011 09:13:06 -0500 Subject: [PATCH 2/2] ZF-3257, ZF11385: CS cleanup of patch - CS cleanup - Cleaned up logic structures; if returning from within an if{} block, no need for an else{}. --- src/Json.php | 84 ++++++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 38 deletions(-) diff --git a/src/Json.php b/src/Json.php index 51bbe650e..de95d3d48 100644 --- a/src/Json.php +++ b/src/Json.php @@ -207,10 +207,11 @@ protected static function _recursiveJsonExprFinder( * @param SimpleXMLElement $simpleXmlElementObject * @return Zend_Json_Expr|string */ - protected static function _getXmlValue($simpleXmlElementObject) { - $pattern = '/^[\s]*new Zend_Json_Expr[\s]*\([\s]*[\"\']{1}(.*)[\"\']{1}[\s]*\)[\s]*$/'; + protected static function _getXmlValue($simpleXmlElementObject) + { + $pattern = '/^[\s]*new Zend[_\\]Json[_\\]Expr[\s]*\([\s]*[\"\']{1}(.*)[\"\']{1}[\s]*\)[\s]*$/'; $matchings = array(); - $match = preg_match ($pattern, $simpleXmlElementObject, $matchings); + $match = preg_match($pattern, $simpleXmlElementObject, $matchings); if ($match) { return new Expr($matchings[1]); } else { @@ -238,56 +239,63 @@ protected static function _getXmlValue($simpleXmlElementObject) { * @param integer $recursionDepth * @return array */ - protected static function _processXml ($simpleXmlElementObject, $ignoreXmlAttributes, $recursionDepth=0) { + protected static function _processXml($simpleXmlElementObject, $ignoreXmlAttributes, $recursionDepth = 0) + { // Keep an eye on how deeply we are involved in recursion. if ($recursionDepth > self::$maxRecursionDepthAllowed) { // XML tree is too deep. Exit now by throwing an exception. throw new RecursionException( - "Function _processXml exceeded the allowed recursion depth of " . - self::$maxRecursionDepthAllowed); - } // End of if ($recursionDepth > self::$maxRecursionDepthAllowed) - $childrens= $simpleXmlElementObject->children(); - $name= $simpleXmlElementObject->getName(); - $value= self::_getXmlValue($simpleXmlElementObject); - $attributes= (array) $simpleXmlElementObject->attributes(); - if (count($childrens)==0) { + "Function _processXml exceeded the allowed recursion depth of " + . self::$maxRecursionDepthAllowed + ); + } + + $children = $simpleXmlElementObject->children(); + $name = $simpleXmlElementObject->getName(); + $value = self::_getXmlValue($simpleXmlElementObject); + $attributes = (array) $simpleXmlElementObject->attributes(); + + if (!count($children)) { if (!empty($attributes) && !$ignoreXmlAttributes) { foreach ($attributes['@attributes'] as $k => $v) { - $attributes['@attributes'][$k]= self::_getXmlValue($v); + $attributes['@attributes'][$k] = self::_getXmlValue($v); } if (!empty($value)) { - $attributes['@text']= $value; + $attributes['@text'] = $value; } return array($name => $attributes); - } else { - return array($name => $value); } - } else { - $childArray= array(); - foreach ($childrens as $child) { - $childname= $child->getName(); - $element= self::_processXml($child,$ignoreXmlAttributes,$recursionDepth+1); - if (array_key_exists($childname, $childArray)) { - if (empty($subChild[$childname])) { - $childArray[$childname]=array($childArray[$childname]); - $subChild[$childname]=true; - } - $childArray[$childname][]= $element[$childname]; - } else { - $childArray[$childname]= $element[$childname]; - } - } - if (!empty($attributes) && !$ignoreXmlAttributes) { - foreach ($attributes['@attributes'] as $k => $v) { - $attributes['@attributes'][$k]= self::_getXmlValue($v); + + return array($name => $value); + } + + $childArray = array(); + foreach ($children as $child) { + $childname = $child->getName(); + $element = self::_processXml($child,$ignoreXmlAttributes,$recursionDepth + 1); + if (array_key_exists($childname, $childArray)) { + if (empty($subChild[$childname])) { + $childArray[$childname] = array($childArray[$childname]); + $subChild[$childname] = true; } - $childArray['@attributes']= $attributes['@attributes']; + $childArray[$childname][] = $element[$childname]; + } else { + $childArray[$childname] = $element[$childname]; } - if (!empty($value)) { - $childArray['@text']= $value; + } + + if (!empty($attributes) && !$ignoreXmlAttributes) { + foreach ($attributes['@attributes'] as $k => $v) { + $attributes['@attributes'][$k] = self::_getXmlValue($v); } - return array($name => $childArray); + $childArray['@attributes'] = $attributes['@attributes']; } + + if (!empty($value)) { + $childArray['@text'] = $value; + } + + return array($name => $childArray); } /**