Skip to content

Commit

Permalink
Describer: uses reference-based detection of array recursion
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Apr 13, 2020
1 parent cc9311a commit 9e525fe
Showing 1 changed file with 25 additions and 24 deletions.
49 changes: 25 additions & 24 deletions src/Tracy/Dumper/Describer.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,16 @@ class Describer
/** @var int[] */
private $references = [];

/** @var int[] */
private $parentArrays = [];


/**
* @return mixed
*/
public function describe(&$var)
public function describe($var)
{
$this->references = [];
$this->references = $this->parentArrays = [];
uksort($this->objectExposers, function ($a, $b): int {
return $b === '' || (class_exists($a, false) && is_subclass_of($a, $b)) ? -1 : 1;
});
Expand All @@ -60,7 +63,7 @@ public function describe(&$var)
/**
* @return mixed
*/
private function describeVar(&$var, int $depth = 0)
private function describeVar($var, int $depth = 0, int $refId = null)
{
switch (true) {
case $var === null:
Expand All @@ -80,6 +83,15 @@ private function describeVar(&$var, int $depth = 0)
}
return (object) ['string' => $s, 'length' => strlen($var)];

case is_array($var) && $refId:
if (in_array($refId, $this->parentArrays, true)) {
return (object) ['stop' => [count($var), true]];
}
$this->parentArrays[] = $refId;
$res = $this->describeArray($var, $depth);
array_pop($this->parentArrays);
return $res;

case is_array($var):
return $this->describeArray($var, $depth);

Expand All @@ -100,29 +112,18 @@ private function describeVar(&$var, int $depth = 0)
*/
private function describeArray(array &$arr, int $depth = 0)
{
static $marker;
if ($marker === null) {
$marker = uniqid("\x00", true);
}
if (count($arr) && (isset($arr[$marker]) || $depth >= $this->maxDepth)) {
return (object) ['stop' => [count($arr) - isset($arr[$marker]), isset($arr[$marker])]];
if (count($arr) && $depth >= $this->maxDepth) {
return (object) ['stop' => [count($arr), false]];
}
$res = [];
try {
$arr[$marker] = true;
foreach ($arr as $k => $v) {
if ($k !== $marker) {
$refId = $this->getReferenceId($arr, $k);
$res[] = [
$this->encodeKey($k),
is_string($k) && isset($this->keysToHide[strtolower($k)])
? (object) ['key' => self::hideValue($v)]
: $this->describeVar($arr[$k], $depth + 1),
] + ($refId ? [2 => $refId] : []);
}
}
} finally {
unset($arr[$marker]);
foreach ($arr as $k => $v) {
$refId = $this->getReferenceId($arr, $k);
$res[] = [
$this->encodeKey($k),
is_string($k) && isset($this->keysToHide[strtolower($k)])
? (object) ['key' => self::hideValue($v)]
: $this->describeVar($arr[$k], $depth + 1, $refId),
] + ($refId ? [2 => $refId] : []);
}
return $res;
}
Expand Down

0 comments on commit 9e525fe

Please sign in to comment.