feature #19079 [Debug] Do not quote numbers in stack trace (c960657)
This PR was merged into the 3.2-dev branch.
Discussion
----------
[Debug] Do not quote numbers in stack trace
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| BC breaks? | yes
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets |
| License | MIT
| Doc PR |
In the debug output from the exception handler, integers and floats are quoted. This adds unnecessary noise to the error page and is just wrong.
Fixing this requires introduces two new type descriptions in the output from getTrace(), so the change is not fully backwards compatible.
Commits
-------
fb10b33
[Debug] Do not quote numbers in stack trace
This commit is contained in:
commit
414a4b4233
@ -1,6 +1,12 @@
|
|||||||
UPGRADE FROM 3.x to 4.0
|
UPGRADE FROM 3.x to 4.0
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
|
Debug
|
||||||
|
-----
|
||||||
|
|
||||||
|
* `FlattenException::getTrace()` now returns additional type descriptions
|
||||||
|
`integer` and `float`.
|
||||||
|
|
||||||
DependencyInjection
|
DependencyInjection
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
@ -92,8 +92,6 @@ class CodeExtension extends \Twig_Extension
|
|||||||
$formattedValue = sprintf('<em>object</em>(<abbr title="%s">%s</abbr>)', $item[1], $short);
|
$formattedValue = sprintf('<em>object</em>(<abbr title="%s">%s</abbr>)', $item[1], $short);
|
||||||
} elseif ('array' === $item[0]) {
|
} elseif ('array' === $item[0]) {
|
||||||
$formattedValue = sprintf('<em>array</em>(%s)', is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
|
$formattedValue = sprintf('<em>array</em>(%s)', is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
|
||||||
} elseif ('string' === $item[0]) {
|
|
||||||
$formattedValue = sprintf("'%s'", htmlspecialchars($item[1], ENT_QUOTES, $this->charset));
|
|
||||||
} elseif ('null' === $item[0]) {
|
} elseif ('null' === $item[0]) {
|
||||||
$formattedValue = '<em>null</em>';
|
$formattedValue = '<em>null</em>';
|
||||||
} elseif ('boolean' === $item[0]) {
|
} elseif ('boolean' === $item[0]) {
|
||||||
@ -101,7 +99,7 @@ class CodeExtension extends \Twig_Extension
|
|||||||
} elseif ('resource' === $item[0]) {
|
} elseif ('resource' === $item[0]) {
|
||||||
$formattedValue = '<em>resource</em>';
|
$formattedValue = '<em>resource</em>';
|
||||||
} else {
|
} else {
|
||||||
$formattedValue = str_replace("\n", '', var_export(htmlspecialchars((string) $item[1], ENT_QUOTES, $this->charset), true));
|
$formattedValue = str_replace("\n", '', htmlspecialchars(var_export($item[1], true), ENT_COMPAT | ENT_SUBSTITUTE, $this->charset));
|
||||||
}
|
}
|
||||||
|
|
||||||
$result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue);
|
$result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue);
|
||||||
@ -174,7 +172,7 @@ class CodeExtension extends \Twig_Extension
|
|||||||
$text = "$text at line $line";
|
$text = "$text at line $line";
|
||||||
|
|
||||||
if (false !== $link = $this->getFileLink($file, $line)) {
|
if (false !== $link = $this->getFileLink($file, $line)) {
|
||||||
$flags = ENT_QUOTES | ENT_SUBSTITUTE;
|
$flags = ENT_COMPAT | ENT_SUBSTITUTE;
|
||||||
|
|
||||||
return sprintf('<a href="%s" title="Click to open this file" class="file_link">%s</a>', htmlspecialchars($link, $flags, $this->charset), $text);
|
return sprintf('<a href="%s" title="Click to open this file" class="file_link">%s</a>', htmlspecialchars($link, $flags, $this->charset), $text);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
3.2.0
|
||||||
|
-----
|
||||||
|
|
||||||
|
* `FlattenException::getTrace()` now returns additional type descriptions
|
||||||
|
`integer` and `float`.
|
||||||
|
|
||||||
|
|
||||||
3.0.0
|
3.0.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
@ -234,6 +234,10 @@ class FlattenException
|
|||||||
$result[$key] = array('null', null);
|
$result[$key] = array('null', null);
|
||||||
} elseif (is_bool($value)) {
|
} elseif (is_bool($value)) {
|
||||||
$result[$key] = array('boolean', $value);
|
$result[$key] = array('boolean', $value);
|
||||||
|
} elseif (is_integer($value)) {
|
||||||
|
$result[$key] = array('integer', $value);
|
||||||
|
} elseif (is_float($value)) {
|
||||||
|
$result[$key] = array('float', $value);
|
||||||
} elseif (is_resource($value)) {
|
} elseif (is_resource($value)) {
|
||||||
$result[$key] = array('resource', get_resource_type($value));
|
$result[$key] = array('resource', get_resource_type($value));
|
||||||
} elseif ($value instanceof \__PHP_Incomplete_Class) {
|
} elseif ($value instanceof \__PHP_Incomplete_Class) {
|
||||||
|
@ -376,8 +376,6 @@ EOF;
|
|||||||
$formattedValue = sprintf('<em>object</em>(%s)', $this->formatClass($item[1]));
|
$formattedValue = sprintf('<em>object</em>(%s)', $this->formatClass($item[1]));
|
||||||
} elseif ('array' === $item[0]) {
|
} elseif ('array' === $item[0]) {
|
||||||
$formattedValue = sprintf('<em>array</em>(%s)', is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
|
$formattedValue = sprintf('<em>array</em>(%s)', is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
|
||||||
} elseif ('string' === $item[0]) {
|
|
||||||
$formattedValue = sprintf("'%s'", $this->escapeHtml($item[1]));
|
|
||||||
} elseif ('null' === $item[0]) {
|
} elseif ('null' === $item[0]) {
|
||||||
$formattedValue = '<em>null</em>';
|
$formattedValue = '<em>null</em>';
|
||||||
} elseif ('boolean' === $item[0]) {
|
} elseif ('boolean' === $item[0]) {
|
||||||
@ -385,7 +383,7 @@ EOF;
|
|||||||
} elseif ('resource' === $item[0]) {
|
} elseif ('resource' === $item[0]) {
|
||||||
$formattedValue = '<em>resource</em>';
|
$formattedValue = '<em>resource</em>';
|
||||||
} else {
|
} else {
|
||||||
$formattedValue = str_replace("\n", '', var_export($this->escapeHtml((string) $item[1]), true));
|
$formattedValue = str_replace("\n", '', $this->escapeHtml(var_export($item[1], true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue);
|
$result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue);
|
||||||
|
@ -190,6 +190,60 @@ class FlattenExceptionTest extends \PHPUnit_Framework_TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testArguments()
|
||||||
|
{
|
||||||
|
$dh = opendir(__DIR__);
|
||||||
|
|
||||||
|
$incomplete = unserialize('O:14:"BogusTestClass":0:{}');
|
||||||
|
|
||||||
|
$exception = $this->createException(array(
|
||||||
|
(object) array('foo' => 1),
|
||||||
|
new NotFoundHttpException(),
|
||||||
|
$incomplete,
|
||||||
|
$dh,
|
||||||
|
function() {},
|
||||||
|
array(1, 2),
|
||||||
|
array('foo' => 123),
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
0.0,
|
||||||
|
'0',
|
||||||
|
'',
|
||||||
|
INF,
|
||||||
|
NAN,
|
||||||
|
));
|
||||||
|
|
||||||
|
$flattened = FlattenException::create($exception);
|
||||||
|
$trace = $flattened->getTrace();
|
||||||
|
$args = $trace[1]['args'];
|
||||||
|
$array = $args[0][1];
|
||||||
|
|
||||||
|
closedir($dh);
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
$this->assertSame($array[$i++], array('object', 'stdClass'));
|
||||||
|
$this->assertSame($array[$i++], array('object', 'Symfony\Component\HttpKernel\Exception\NotFoundHttpException'));
|
||||||
|
$this->assertSame($array[$i++], array('incomplete-object', 'BogusTestClass'));
|
||||||
|
$this->assertSame($array[$i++], array('resource', 'stream'));
|
||||||
|
$this->assertSame($array[$i++], array('object', 'Closure'));
|
||||||
|
$this->assertSame($array[$i++], array('array', array(array('integer', 1), array('integer', 2))));
|
||||||
|
$this->assertSame($array[$i++], array('array', array('foo' => array('integer', 123))));
|
||||||
|
$this->assertSame($array[$i++], array('null', null));
|
||||||
|
$this->assertSame($array[$i++], array('boolean', true));
|
||||||
|
$this->assertSame($array[$i++], array('boolean', false));
|
||||||
|
$this->assertSame($array[$i++], array('integer', 0));
|
||||||
|
$this->assertSame($array[$i++], array('float', 0.0));
|
||||||
|
$this->assertSame($array[$i++], array('string', '0'));
|
||||||
|
$this->assertSame($array[$i++], array('string', ''));
|
||||||
|
$this->assertSame($array[$i++], array('float', INF));
|
||||||
|
|
||||||
|
// assertEquals() does not like NAN values.
|
||||||
|
$this->assertEquals($array[$i][0], 'float');
|
||||||
|
$this->assertTrue(is_nan($array[$i++][1]));
|
||||||
|
}
|
||||||
|
|
||||||
public function testRecursionInArguments()
|
public function testRecursionInArguments()
|
||||||
{
|
{
|
||||||
$a = array('foo', array(2, &$a));
|
$a = array('foo', array(2, &$a));
|
||||||
@ -216,6 +270,9 @@ class FlattenExceptionTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$flattened = FlattenException::create($exception);
|
$flattened = FlattenException::create($exception);
|
||||||
$trace = $flattened->getTrace();
|
$trace = $flattened->getTrace();
|
||||||
|
|
||||||
|
$this->assertSame($trace[1]['args'][0], array('array', array('array', '*SKIPPED over 10000 entries*')));
|
||||||
|
|
||||||
$serializeTrace = serialize($trace);
|
$serializeTrace = serialize($trace);
|
||||||
|
|
||||||
$this->assertContains('*SKIPPED over 10000 entries*', $serializeTrace);
|
$this->assertContains('*SKIPPED over 10000 entries*', $serializeTrace);
|
||||||
@ -226,45 +283,4 @@ class FlattenExceptionTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
return new \Exception();
|
return new \Exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSetTraceIncompleteClass()
|
|
||||||
{
|
|
||||||
$flattened = FlattenException::create(new \Exception('test', 123));
|
|
||||||
$flattened->setTrace(
|
|
||||||
array(
|
|
||||||
array(
|
|
||||||
'file' => __FILE__,
|
|
||||||
'line' => 123,
|
|
||||||
'function' => 'test',
|
|
||||||
'args' => array(
|
|
||||||
unserialize('O:14:"BogusTestClass":0:{}'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
'foo.php', 123
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->assertEquals(array(
|
|
||||||
array(
|
|
||||||
'message' => 'test',
|
|
||||||
'class' => 'Exception',
|
|
||||||
'trace' => array(
|
|
||||||
array(
|
|
||||||
'namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => '',
|
|
||||||
'file' => 'foo.php', 'line' => 123,
|
|
||||||
'args' => array(),
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => 'test',
|
|
||||||
'file' => __FILE__, 'line' => 123,
|
|
||||||
'args' => array(
|
|
||||||
array(
|
|
||||||
'incomplete-object', 'BogusTestClass',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
), $flattened->toArray());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user