1
0
mirror of https://github.com/Seldaek/monolog.git synced 2025-08-06 13:16:39 +02:00

Merge pull request #1102 from TomzxForks/features/1094-configure-normalize-depth-and-item-count

Configurable JsonFormatter maximum normalized depth and number of items
This commit is contained in:
Jordi Boggiano
2018-06-08 12:03:19 +02:00
committed by GitHub
2 changed files with 73 additions and 4 deletions

View File

@@ -27,6 +27,8 @@ class JsonFormatter extends NormalizerFormatter
protected $batchMode; protected $batchMode;
protected $appendNewline; protected $appendNewline;
protected $maxNormalizeDepth = 9;
protected $maxNormalizeItemCount = 1000;
/** /**
* @var bool * @var bool
@@ -59,6 +61,32 @@ class JsonFormatter extends NormalizerFormatter
return $this->appendNewline; return $this->appendNewline;
} }
/**
* The maximum number of normalization levels to go through
*/
public function getMaxNormalizeDepth(): int
{
return $this->maxNormalizeDepth;
}
public function setMaxNormalizeDepth(int $maxNormalizeDepth): void
{
$this->maxNormalizeDepth = $maxNormalizeDepth;
}
/**
* The maximum number of items to normalize per level
*/
public function getMaxNormalizeItemCount(): int
{
return $this->maxNormalizeItemCount;
}
public function setMaxNormalizeItemCount(int $maxNormalizeItemCount): void
{
$this->maxNormalizeItemCount = $maxNormalizeItemCount;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@@ -122,8 +150,8 @@ class JsonFormatter extends NormalizerFormatter
*/ */
protected function normalize($data, int $depth = 0) protected function normalize($data, int $depth = 0)
{ {
if ($depth > 9) { if ($depth > $this->maxNormalizeDepth) {
return 'Over 9 levels deep, aborting normalization'; return 'Over '.$this->maxNormalizeDepth.' levels deep, aborting normalization';
} }
if (is_array($data) || $data instanceof \Traversable) { if (is_array($data) || $data instanceof \Traversable) {
@@ -131,8 +159,8 @@ class JsonFormatter extends NormalizerFormatter
$count = 1; $count = 1;
foreach ($data as $key => $value) { foreach ($data as $key => $value) {
if ($count++ >= 1000) { if ($count++ >= $this->maxNormalizeItemCount) {
$normalized['...'] = 'Over 1000 items, aborting normalization'; $normalized['...'] = 'Over '.$this->maxNormalizeItemCount.' items, aborting normalization';
break; break;
} }
$normalized[$key] = $this->normalize($value, $depth + 1); $normalized[$key] = $this->normalize($value, $depth + 1);

View File

@@ -110,6 +110,47 @@ class JsonFormatterTest extends TestCase
$this->assertContextContainsFormattedException($formattedThrowable, $message); $this->assertContextContainsFormattedException($formattedThrowable, $message);
} }
public function testMaxNormalizeDepth()
{
$formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, true);
$formatter->setMaxNormalizeDepth(1);
$throwable = new \Error('Foo');
$message = $this->formatRecordWithExceptionInContext($formatter, $throwable);
$this->assertContextContainsFormattedException('"Over 1 levels deep, aborting normalization"', $message);
}
public function testMaxNormalizeItemCountWith0ItemsMax()
{
$formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, true);
$formatter->setMaxNormalizeDepth(9);
$formatter->setMaxNormalizeItemCount(0);
$throwable = new \Error('Foo');
$message = $this->formatRecordWithExceptionInContext($formatter, $throwable);
$this->assertEquals(
'{"...":"Over 0 items, aborting normalization"}'."\n",
$message
);
}
public function testMaxNormalizeItemCountWith3ItemsMax()
{
$formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, true);
$formatter->setMaxNormalizeDepth(9);
$formatter->setMaxNormalizeItemCount(3);
$throwable = new \Error('Foo');
$message = $this->formatRecordWithExceptionInContext($formatter, $throwable);
$this->assertEquals(
'{"level_name":"CRITICAL","channel":"core","...":"Over 3 items, aborting normalization"}'."\n",
$message
);
}
/** /**
* @param string $expected * @param string $expected
* @param string $actual * @param string $actual