Skip to content

Commit

Permalink
[VarDumper] Display invisible characters
Browse files Browse the repository at this point in the history
  • Loading branch information
alamirault authored and nicolas-grekas committed Jan 26, 2023
1 parent e169dd4 commit 967f55b
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ CHANGELOG
* Add caster for `WeakMap`
* Add support of named arguments to `dd()` and `dump()` to display the argument name
* Add support for `Relay\Relay`
* Add display of invisible characters

6.2
---
Expand Down
9 changes: 9 additions & 0 deletions Dumper/CliDumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class CliDumper extends AbstractDumper
"\r" => '\r',
"\033" => '\e',
];
protected static $unicodeCharsRx = "/[\u{00A0}\u{00AD}\u{034F}\u{061C}\u{115F}\u{1160}\u{17B4}\u{17B5}\u{180E}\u{2000}-\u{200F}\u{202F}\u{205F}\u{2060}-\u{2064}\u{206A}-\u{206F}\u{3000}\u{2800}\u{3164}\u{FEFF}\u{FFA0}\u{1D159}\u{1D173}-\u{1D17A}]/u";

protected $collapseNextHash = false;
protected $expandNextHash = false;
Expand Down Expand Up @@ -450,6 +451,14 @@ protected function style(string $style, string $value, array $attr = []): string
return $s.$endCchr;
}, $value, -1, $cchrCount);

if (!($attr['binary'] ?? false)) {
$value = preg_replace_callback(static::$unicodeCharsRx, function ($c) use (&$cchrCount, $startCchr, $endCchr) {
++$cchrCount;

return $startCchr.'\u{'.strtoupper(dechex(mb_ord($c[0]))).'}'.$endCchr;
}, $value);
}

if ($this->colors) {
if ($cchrCount && "\033" === $value[0]) {
$value = substr($value, \strlen($startCchr));
Expand Down
8 changes: 7 additions & 1 deletion Dumper/HtmlDumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,6 @@ protected function style(string $style, string $value, array $attr = []): string
} elseif ('private' === $style) {
$style .= sprintf(' title="Private property defined in class:
`%s`"', esc($this->utf8Encode($attr['class'])));
}
$map = static::$controlCharsMap;

if (isset($attr['ellipsis'])) {
$class = 'sf-dump-ellipsis';
Expand All @@ -881,6 +880,7 @@ protected function style(string $style, string $value, array $attr = []): string
}
}

$map = static::$controlCharsMap;
$v = "<span class=sf-dump-{$style}>".preg_replace_callback(static::$controlCharsRx, function ($c) use ($map) {
$s = $b = '<span class="sf-dump-default';
$c = $c[$i = 0];
Expand All @@ -903,6 +903,12 @@ protected function style(string $style, string $value, array $attr = []): string
return $s.'</span>';
}, $v).'</span>';

if (!($attr['binary'] ?? false)) {
$v = preg_replace_callback(static::$unicodeCharsRx, function ($c) {
return '<span class="sf-dump-default>\u{'.strtoupper(dechex(mb_ord($c[0]))).'}</span>';
}, $v);
}

if (isset($attr['file']) && $href = $this->getSourceLink($attr['file'], $attr['line'] ?? 0)) {
$attr['href'] = $href;
}
Expand Down
3 changes: 2 additions & 1 deletion Tests/Dumper/CliDumperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public function testGet()

$this->assertStringMatchesFormat(
<<<EOTXT
array:24 [
array:25 [
"number" => 1
0 => &1 null
"const" => 1.1
Expand All @@ -66,6 +66,7 @@ public function testGet()
é\\x01test\\t\\n
ing
"""
"bo\\u{FEFF}m" => "te\\u{FEFF}st"
"[]" => []
"res" => stream resource {@{$res}
%A wrapper_type: "plainfile"
Expand Down
3 changes: 2 additions & 1 deletion Tests/Dumper/HtmlDumperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public function testGet()

$this->assertStringMatchesFormat(
<<<EOTXT
<foo></foo><bar><span class=sf-dump-note>array:24</span> [<samp data-depth=1 class=sf-dump-expanded>
<foo></foo><bar><span class=sf-dump-note>array:25</span> [<samp data-depth=1 class=sf-dump-expanded>
"<span class=sf-dump-key>number</span>" => <span class=sf-dump-num>1</span>
<span class=sf-dump-key>0</span> => <a class=sf-dump-ref href=#{$dumpId}-ref01 title="2 occurrences">&amp;1</a> <span class=sf-dump-const>null</span>
"<span class=sf-dump-key>const</span>" => <span class=sf-dump-num>1.1</span>
Expand All @@ -69,6 +69,7 @@ public function testGet()
<span class=sf-dump-str title="11 binary or non-UTF-8 characters">&#233;<span class="sf-dump-default">\\x01</span>test<span class="sf-dump-default">\\t</span><span class="sf-dump-default sf-dump-ns">\\n</span></span>
<span class=sf-dump-str title="11 binary or non-UTF-8 characters">ing</span>
"""
"<span class=sf-dump-key>bo<span class="sf-dump-default>\\u{FEFF}</span>m</span>" => "<span class=sf-dump-str title="5 characters">te<span class="sf-dump-default>\\u{FEFF}</span>st</span>"
"<span class=sf-dump-key>[]</span>" => []
"<span class=sf-dump-key>res</span>" => <span class=sf-dump-note>stream resource</span> <a class=sf-dump-ref>@{$res}</a><samp data-depth=2 class=sf-dump-compact>
%A <span class=sf-dump-meta>wrapper_type</span>: "<span class=sf-dump-str title="9 characters">plainfile</span>"
Expand Down
13 changes: 11 additions & 2 deletions Tests/Fixtures/dumb-var.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\VarDumper\Tests\Fixture;

if (!class_exists(\Symfony\Component\VarDumper\Tests\Fixture\DumbFoo::class)) {
Expand All @@ -17,8 +26,8 @@ class DumbFoo

$var = [
'number' => 1, null,
'const' => 1.1, true, false, NAN, INF, -INF, PHP_INT_MAX,
'str' => "déjà\n", "\xE9\x01test\t\ning",
'const' => 1.1, true, false, \NAN, \INF, -\INF, \PHP_INT_MAX,
'str' => "déjà\n", "\xE9\x01test\t\ning", "bo\u{feff}m" => "te\u{feff}st",
'[]' => [],
'res' => $g,
'obj' => $foo,
Expand Down

0 comments on commit 967f55b

Please sign in to comment.