[VarDumper] edge case fixes

This commit is contained in:
Nicolas Grekas 2014-09-26 09:07:47 +02:00
parent 15dfb0614e
commit 10943d9c6d
15 changed files with 58 additions and 50 deletions

View File

@ -41,7 +41,8 @@ class Configuration implements ConfigurationInterface
->min(-1) ->min(-1)
->defaultValue(-1) ->defaultValue(-1)
->end() ->end()
->end(); ->end()
;
return $treeBuilder; return $treeBuilder;
} }

View File

@ -18,7 +18,7 @@
<div class="sf-toolbar-info-piece"> <div class="sf-toolbar-info-piece">
in in
{% if dump.file %} {% if dump.file %}
{% set link = dump.file|file_link(dump.line) }} %} {% set link = dump.file|file_link(dump.line) %}
{% if link %} {% if link %}
<a href="{{ link }}" title="{{ dump.file }}">{{ dump.name }}</a> <a href="{{ link }}" title="{{ dump.file }}">{{ dump.name }}</a>
{% else %} {% else %}
@ -76,7 +76,7 @@
<li class="sf-dump sf-reset"> <li class="sf-dump sf-reset">
in in
{% if dump.line %} {% if dump.line %}
{% set link = dump.file|file_link(dump.line) }} %} {% set link = dump.file|file_link(dump.line) %}
{% if link %} {% if link %}
<a href="{{ link }}" title="{{ dump.file }}">{{ dump.name }}</a> <a href="{{ link }}" title="{{ dump.file }}">{{ dump.name }}</a>
{% else %} {% else %}

View File

@ -15,7 +15,6 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Stopwatch\Stopwatch; use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Component\VarDumper\Cloner\Data; use Symfony\Component\VarDumper\Cloner\Data;
use Symfony\Component\VarDumper\Dumper\JsonDumper;
use Symfony\Component\VarDumper\Dumper\CliDumper; use Symfony\Component\VarDumper\Dumper\CliDumper;
use Symfony\Component\VarDumper\Dumper\HtmlDumper; use Symfony\Component\VarDumper\Dumper\HtmlDumper;
use Symfony\Component\VarDumper\Dumper\DataDumperInterface; use Symfony\Component\VarDumper\Dumper\DataDumperInterface;
@ -158,8 +157,6 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
{ {
if ('html' === $format) { if ('html' === $format) {
$dumper = new HtmlDumper(); $dumper = new HtmlDumper();
} elseif ('json' === $format) {
$dumper = new JsonDumper();
} else { } else {
throw new \InvalidArgumentException(sprintf('Invalid dump format: %s', $format)); throw new \InvalidArgumentException(sprintf('Invalid dump format: %s', $format));
} }

View File

@ -22,11 +22,13 @@ class CasterStub extends Stub
{ {
public function __construct($value, $class = '') public function __construct($value, $class = '')
{ {
$this->class = $class;
$this->value = $value;
switch (gettype($value)) { switch (gettype($value)) {
case 'object': case 'object':
$this->type = self::TYPE_OBJECT; $this->type = self::TYPE_OBJECT;
$this->class = get_class($value); $this->class = get_class($value);
$this->value = spl_object_hash($value);
$this->cut = -1; $this->cut = -1;
break; break;
@ -40,7 +42,6 @@ class CasterStub extends Stub
case 'unknown type': case 'unknown type':
$this->type = self::TYPE_RESOURCE; $this->type = self::TYPE_RESOURCE;
$this->class = @get_resource_type($value); $this->class = @get_resource_type($value);
$this->value = (int) $value;
$this->cut = -1; $this->cut = -1;
break; break;
@ -49,13 +50,8 @@ class CasterStub extends Stub
$this->type = self::TYPE_STRING; $this->type = self::TYPE_STRING;
$this->class = preg_match('//u', $value) ? self::STRING_UTF8 : self::STRING_BINARY; $this->class = preg_match('//u', $value) ? self::STRING_UTF8 : self::STRING_BINARY;
$this->cut = self::STRING_BINARY === $this->class ? strlen($value) : (function_exists('iconv_strlen') ? iconv_strlen($value, 'UTF-8') : -1); $this->cut = self::STRING_BINARY === $this->class ? strlen($value) : (function_exists('iconv_strlen') ? iconv_strlen($value, 'UTF-8') : -1);
break; $this->value = '';
} }
// No break;
default:
$this->class = $class;
$this->value = $value;
break; break;
} }
} }

View File

@ -174,14 +174,14 @@ abstract class AbstractCloner implements ClonerInterface
/** /**
* Casts an object to an array representation. * Casts an object to an array representation.
* *
* @param object $obj The object itself.
* @param Stub $stub The Stub for the casted object. * @param Stub $stub The Stub for the casted object.
* @param bool $isNested True if the object is nested in the dumped structure. * @param bool $isNested True if the object is nested in the dumped structure.
* *
* @return array The object casted as array. * @return array The object casted as array.
*/ */
protected function castObject($obj, Stub $stub, $isNested) protected function castObject(Stub $stub, $isNested)
{ {
$obj = $stub->value;
$class = $stub->class; $class = $stub->class;
if (isset($this->classInfo[$class])) { if (isset($this->classInfo[$class])) {
@ -225,15 +225,15 @@ abstract class AbstractCloner implements ClonerInterface
/** /**
* Casts a resource to an array representation. * Casts a resource to an array representation.
* *
* @param resource $res The resource.
* @param Stub $stub The Stub for the casted resource. * @param Stub $stub The Stub for the casted resource.
* @param bool $isNested True if the object is nested in the dumped structure. * @param bool $isNested True if the object is nested in the dumped structure.
* *
* @return array The resource casted as array. * @return array The resource casted as array.
*/ */
protected function castResource($res, Stub $stub, $isNested) protected function castResource(Stub $stub, $isNested)
{ {
$a = array(); $a = array();
$res = $stub->value;
$type = $stub->class; $type = $stub->class;
if (!empty($this->casters[':'.$type])) { if (!empty($this->casters[':'.$type])) {

View File

@ -200,8 +200,8 @@ class Data
*/ */
public static function utf8Encode($s) public static function utf8Encode($s)
{ {
if (function_exists('iconv')) { if (function_exists('mb_convert_encoding')) {
return iconv('CP1252', 'UTF-8', $s); return mb_convert_encoding($s, 'UTF-8', 'CP1252');
} }
$s .= $s; $s .= $s;

View File

@ -95,16 +95,18 @@ class ExtCloner extends AbstractCloner
$stub = new Stub(); $stub = new Stub();
$stub->type = Stub::TYPE_OBJECT; $stub->type = Stub::TYPE_OBJECT;
$stub->class = $zval['object_class']; $stub->class = $zval['object_class'];
$stub->value = $h; $stub->value = $v;
$a = $this->castObject($v, $stub, 0 < $i); $a = $this->castObject($stub, 0 < $i);
if (Stub::TYPE_OBJECT !== $stub->type) { if ($v !== $stub->value) {
break; if (Stub::TYPE_OBJECT !== $stub->type) {
break;
}
$h = spl_object_hash($stub->value);
} }
$h = $stub->value; $stub->value = null;
$stub->value = '';
if (0 <= $maxItems && $maxItems <= $pos) { if (0 <= $maxItems && $maxItems <= $pos) {
$stub->cut = count($a); $stub->cut = count($a);
$a = array(); $a = null;
} }
} }
if (empty($softRefs[$h])) { if (empty($softRefs[$h])) {
@ -112,6 +114,7 @@ class ExtCloner extends AbstractCloner
} else { } else {
$stub = $softRefs[$h]; $stub = $softRefs[$h];
$stub->ref = ++$refs; $stub->ref = ++$refs;
$a = null;
} }
break; break;
@ -120,16 +123,18 @@ class ExtCloner extends AbstractCloner
$stub = new Stub(); $stub = new Stub();
$stub->type = Stub::TYPE_RESOURCE; $stub->type = Stub::TYPE_RESOURCE;
$stub->class = $zval['resource_type']; $stub->class = $zval['resource_type'];
$stub->value = $h; $stub->value = $v;
$a = $this->castResource($v, $stub, 0 < $i); $a = $this->castResource($stub, 0 < $i);
if (Stub::TYPE_RESOURCE !== $stub->type) { if ($v !== $stub->value) {
break; if (Stub::TYPE_RESOURCE !== $stub->type) {
break;
}
$h = (int) $stub->value;
} }
$h = $stub->value; $stub->value = null;
$stub->value = '';
if (0 <= $maxItems && $maxItems <= $pos) { if (0 <= $maxItems && $maxItems <= $pos) {
$stub->cut = count($a); $stub->cut = count($a);
$a = array(); $a = null;
} }
} }
if (empty($softRefs[$h])) { if (empty($softRefs[$h])) {
@ -137,6 +142,7 @@ class ExtCloner extends AbstractCloner
} else { } else {
$stub = $softRefs[$h]; $stub = $softRefs[$h];
$stub->ref = ++$refs; $stub->ref = ++$refs;
$a = null;
} }
break; break;
} }

View File

@ -101,16 +101,18 @@ class PhpCloner extends AbstractCloner
$stub = new Stub(); $stub = new Stub();
$stub->type = Stub::TYPE_OBJECT; $stub->type = Stub::TYPE_OBJECT;
$stub->class = get_class($v); $stub->class = get_class($v);
$stub->value = $h; $stub->value = $v;
$a = $this->castObject($v, $stub, 0 < $i); $a = $this->castObject($stub, 0 < $i);
if (Stub::TYPE_OBJECT !== $stub->type) { if ($v !== $stub->value) {
break; if (Stub::TYPE_OBJECT !== $stub->type) {
break;
}
$h = spl_object_hash($stub->value);
} }
$h = $stub->value; $stub->value = null;
$stub->value = '';
if (0 <= $maxItems && $maxItems <= $pos) { if (0 <= $maxItems && $maxItems <= $pos) {
$stub->cut = count($a); $stub->cut = count($a);
$a = array(); $a = null;
} }
} }
if (empty($softRefs[$h])) { if (empty($softRefs[$h])) {
@ -118,6 +120,7 @@ class PhpCloner extends AbstractCloner
} else { } else {
$stub = $softRefs[$h]; $stub = $softRefs[$h];
$stub->ref = ++$refs; $stub->ref = ++$refs;
$a = null;
} }
break; break;
@ -127,16 +130,18 @@ class PhpCloner extends AbstractCloner
$stub = new Stub(); $stub = new Stub();
$stub->type = Stub::TYPE_RESOURCE; $stub->type = Stub::TYPE_RESOURCE;
$stub->class = get_resource_type($v); $stub->class = get_resource_type($v);
$stub->value = $h; $stub->value = $v;
$a = $this->castResource($v, $stub, 0 < $i); $a = $this->castResource($stub, 0 < $i);
if (Stub::TYPE_RESOURCE !== $stub->type) { if ($v !== $stub->value) {
break; if (Stub::TYPE_RESOURCE !== $stub->type) {
break;
}
$h = (int) $stub->value;
} }
$h = $stub->value; $stub->value = null;
$stub->value = '';
if (0 <= $maxItems && $maxItems <= $pos) { if (0 <= $maxItems && $maxItems <= $pos) {
$stub->cut = count($a); $stub->cut = count($a);
$a = array(); $a = null;
} }
} }
if (empty($softRefs[$h])) { if (empty($softRefs[$h])) {
@ -144,6 +149,7 @@ class PhpCloner extends AbstractCloner
} else { } else {
$stub = $softRefs[$h]; $stub = $softRefs[$h];
$stub->ref = ++$refs; $stub->ref = ++$refs;
$a = null;
} }
break; break;
} }

View File

@ -40,6 +40,7 @@ class CliDumperTest extends \PHPUnit_Framework_TestCase
$out = ob_get_clean(); $out = ob_get_clean();
$closureLabel = PHP_VERSION_ID >= 50400 ? 'public method' : 'function'; $closureLabel = PHP_VERSION_ID >= 50400 ? 'public method' : 'function';
$out = preg_replace('/[ \t]+$/m', '', $out); $out = preg_replace('/[ \t]+$/m', '', $out);
$intMax = PHP_INT_MAX;
$this->assertSame( $this->assertSame(
<<<EOTXT <<<EOTXT
@ -52,7 +53,7 @@ array:25 [
3 => NAN 3 => NAN
4 => INF 4 => INF
5 => -INF 5 => -INF
6 => 9223372036854775807 6 => {$intMax}
"str" => "déjà" "str" => "déjà"
7 => b"é" 7 => b"é"
"[]" => [] "[]" => []

View File

@ -43,6 +43,7 @@ class HtmlDumperTest extends \PHPUnit_Framework_TestCase
$closureLabel = PHP_VERSION_ID >= 50400 ? 'public method' : 'function'; $closureLabel = PHP_VERSION_ID >= 50400 ? 'public method' : 'function';
$out = preg_replace('/[ \t]+$/m', '', $out); $out = preg_replace('/[ \t]+$/m', '', $out);
$var['file'] = htmlspecialchars($var['file'], ENT_QUOTES, 'UTF-8'); $var['file'] = htmlspecialchars($var['file'], ENT_QUOTES, 'UTF-8');
$intMax = PHP_INT_MAX;
$this->assertSame( $this->assertSame(
<<<EOTXT <<<EOTXT
@ -55,7 +56,7 @@ class HtmlDumperTest extends \PHPUnit_Framework_TestCase
<span class=sf-dump-meta>3</span> => <span class=sf-dump-num>NAN</span> <span class=sf-dump-meta>3</span> => <span class=sf-dump-num>NAN</span>
<span class=sf-dump-meta>4</span> => <span class=sf-dump-num>INF</span> <span class=sf-dump-meta>4</span> => <span class=sf-dump-num>INF</span>
<span class=sf-dump-meta>5</span> => <span class=sf-dump-num>-INF</span> <span class=sf-dump-meta>5</span> => <span class=sf-dump-num>-INF</span>
<span class=sf-dump-meta>6</span> => <span class=sf-dump-num>9223372036854775807</span> <span class=sf-dump-meta>6</span> => <span class=sf-dump-num>{$intMax}</span>
"<span class=sf-dump-meta>str</span>" => "<span class=sf-dump-str>déjà</span>" "<span class=sf-dump-meta>str</span>" => "<span class=sf-dump-str>déjà</span>"
<span class=sf-dump-meta>7</span> => b"<span class=sf-dump-str>é</span>" <span class=sf-dump-meta>7</span> => b"<span class=sf-dump-str>é</span>"
"<span class=sf-dump-meta>[]</span>" => [] "<span class=sf-dump-meta>[]</span>" => []