Skip to content

Loading…

fixed 4614: infinite loop in Zend\Log\Formatter::normalize #4616

Closed
wants to merge 2 commits into from

2 participants

@marc-mabe
Zend Framework member

No description provided.

@marc-mabe
Zend Framework member

This is the only fix I found for #4614

Because of the PHP bug it's impossible to call normalize for each array entry - so a json_encode on the first level have to be enough and in my opinion it's enough for logging.

It would be helpful if the recursion position would be marked as RECURSION but this is not possible with json_encode -> so it's marked as null

@marc-mabe
Zend Framework member

Also set the options JSON_UNESCAPED_[SLASHES|UNICODE] if possible to generate better readable error messages

@weierophinney weierophinney added a commit that referenced this pull request
@weierophinney weierophinney Merge branch 'hotfix/4616' into develop
Forward port #4616
cf440b8
@weierophinney weierophinney added a commit that closed this pull request
@weierophinney weierophinney Merge branch 'hotfix/4616'
Close #4616
Fixes #4614
3d855c1
@ghost Unknown pushed a commit that referenced this pull request
@weierophinney weierophinney Merge branch 'hotfix/4616'
Close #4616
Fixes #4614
9079305
@weierophinney weierophinney added a commit to zendframework/zend-log that referenced this pull request
@weierophinney weierophinney Merge pull request zendframework/zf2#4616 from marc-mabe/hotfix/4614
fixed 4614: infinite loop in Zend\Log\Formatter::normalize
eb94e73
@weierophinney weierophinney added a commit to zendframework/zend-log that referenced this pull request
@weierophinney weierophinney Merge branch 'hotfix/4616' a6fa26b
@weierophinney weierophinney added a commit to zendframework/zend-log that referenced this pull request
@weierophinney weierophinney Merge branch 'hotfix/4616' into develop 43d002a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Showing with 43 additions and 8 deletions.
  1. +15 −8 library/Zend/Log/Formatter/Base.php
  2. +28 −0 tests/ZendTest/Log/Formatter/BaseTest.php
View
23 library/Zend/Log/Formatter/Base.php
@@ -11,6 +11,7 @@
use DateTime;
use Traversable;
+use Zend\Stdlib\ErrorHandler;
class Base implements FormatterInterface
{
@@ -75,16 +76,21 @@ protected function normalize($value)
return $value;
}
+ // better readable JSON
+ static $jsonFlags;
+ if ($jsonFlags === null) {
+ $jsonFlags = 0;
+ $jsonFlags |= defined('JSON_UNESCAPED_SLASHES') ? JSON_UNESCAPED_SLASHES : 0;
+ $jsonFlags |= defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : 0;
+ }
+
+ ErrorHandler::start();
if ($value instanceof DateTime) {
$value = $value->format($this->getDateTimeFormat());
- } elseif (is_array($value) || $value instanceof Traversable) {
- if ($value instanceof Traversable) {
- $value = iterator_to_array($value);
- }
- foreach ($value as $key => $subvalue) {
- $value[$key] = $this->normalize($subvalue);
- }
- $value = json_encode($value);
+ } elseif ($value instanceof Traversable) {
+ $value = json_encode(iterator_to_array($value), $jsonFlags);
+ } elseif (is_array($value)) {
+ $value = json_encode($value, $jsonFlags);
} elseif (is_object($value) && !method_exists($value, '__toString')) {
$value = sprintf('object(%s) %s', get_class($value), json_encode($value));
} elseif (is_resource($value)) {
@@ -92,6 +98,7 @@ protected function normalize($value)
} elseif (!is_object($value)) {
$value = gettype($value);
}
+ ErrorHandler::stop();
return (string) $value;
}
View
28 tests/ZendTest/Log/Formatter/BaseTest.php
@@ -121,4 +121,32 @@ public function testFormatAllTypes()
$this->assertEquals($outputExpected, $formatter->format($event));
}
+
+ public function testFormatNoInfiniteLoopOnSelfReferencingArrayValues()
+ {
+ $datetime = new DateTime();
+ $formatter = new BaseFormatter();
+
+ $selfRefArr = array();
+ $selfRefArr['selfRefArr'] = & $selfRefArr;
+
+ $event = array(
+ 'timestamp' => $datetime,
+ 'priority' => 1,
+ 'message' => 'tottakai',
+ 'extra' => array(
+ 'selfRefArr' => $selfRefArr,
+ ),
+ );
+ $outputExpected = array(
+ 'timestamp' => $datetime->format($formatter->getDateTimeFormat()),
+ 'priority' => 1,
+ 'message' => 'tottakai',
+ 'extra' => array(
+ 'selfRefArr' => '{"selfRefArr":{"selfRefArr":null}}',
+ ),
+ );
+
+ $this->assertEquals($outputExpected, $formatter->format($event));
+ }
}
Something went wrong with that request. Please try again.