bug #13351 [VarDumper] fix very special vars handling (nicolas-grekas)
This PR was merged into the 2.6 branch.
Discussion
----------
[VarDumper] fix very special vars handling
| Q | A
| ------------- | ---
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #13235
| License | MIT
| Doc PR | -
Commits
-------
e26dc2c
[VarDumper] fix very special vars handling
This commit is contained in:
commit
c6695d1e8b
@ -50,7 +50,7 @@ class DumpDataCollectorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame($xDump, $dump);
|
||||
|
||||
$this->assertStringStartsWith(
|
||||
'a:1:{i:0;a:5:{s:4:"data";O:39:"Symfony\Component\VarDumper\Cloner\Data":4:{s:45:"Symfony\Component\VarDumper\Cloner\Datadata";a:1:{i:0;a:1:{i:0;i:123;}}s:49:"Symfony\Component\VarDumper\Cloner\DatamaxDepth";i:-1;s:57:"Symfony\Component\VarDumper\Cloner\DatamaxItemsPerDepth";i:-1;s:54:"Symfony\Component\VarDumper\Cloner\DatauseRefHandles";i:-1;}s:4:"name";s:25:"DumpDataCollectorTest.php";s:4:"file";s:',
|
||||
'a:1:{i:0;a:5:{s:4:"data";O:39:"Symfony\Component\VarDumper\Cloner\Data":4:{s:45:"Symfony\Component\VarDumper\Cloner\Datadata";a:1:{i:0;a:1:{i:0;i:123;}}s:49:"Symfony\Component\VarDumper\Cloner\DatamaxDepth";i:20;s:57:"Symfony\Component\VarDumper\Cloner\DatamaxItemsPerDepth";i:-1;s:54:"Symfony\Component\VarDumper\Cloner\DatauseRefHandles";i:-1;}s:4:"name";s:25:"DumpDataCollectorTest.php";s:4:"file";s:',
|
||||
str_replace("\0", '', $collector->serialize())
|
||||
);
|
||||
|
||||
|
@ -82,6 +82,7 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
|
||||
protected $maxItems = 2500;
|
||||
protected $maxString = -1;
|
||||
protected $useExt;
|
||||
|
||||
private $casters = array();
|
||||
private $prevErrorHandler;
|
||||
@ -98,6 +99,7 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
$casters = static::$defaultCasters;
|
||||
}
|
||||
$this->addCasters($casters);
|
||||
$this->useExt = extension_loaded('symfony_debug');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,7 +17,7 @@ namespace Symfony\Component\VarDumper\Cloner;
|
||||
class Data
|
||||
{
|
||||
private $data;
|
||||
private $maxDepth = -1;
|
||||
private $maxDepth = 20;
|
||||
private $maxItemsPerDepth = -1;
|
||||
private $useRefHandles = -1;
|
||||
|
||||
|
@ -24,7 +24,7 @@ class VarCloner extends AbstractCloner
|
||||
*/
|
||||
protected function doClone($var)
|
||||
{
|
||||
$useExt = extension_loaded('symfony_debug');
|
||||
$useExt = $this->useExt;
|
||||
$i = 0; // Current iteration position in $queue
|
||||
$len = 1; // Length of $queue
|
||||
$pos = 0; // Number of cloned items past the first level
|
||||
@ -120,7 +120,19 @@ class VarCloner extends AbstractCloner
|
||||
$stub->type = Stub::TYPE_ARRAY;
|
||||
$stub->class = Stub::ARRAY_ASSOC;
|
||||
$stub->value = $zval['array_count'] ?: count($v);
|
||||
|
||||
$a = $v;
|
||||
$a[] = null;
|
||||
$h = count($v);
|
||||
array_pop($a);
|
||||
|
||||
// Happens with copies of $GLOBALS
|
||||
if ($h !== $stub->value) {
|
||||
$a = array();
|
||||
foreach ($v as $gk => &$gv) {
|
||||
$a[$gk] =& $gv;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -104,8 +104,153 @@ array:25 [
|
||||
|
||||
EOTXT
|
||||
,
|
||||
|
||||
$out
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
*/
|
||||
public function testSpecialVars56()
|
||||
{
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
$this->markTestSkipped('PHP 5.6 is required');
|
||||
}
|
||||
|
||||
$var = $this->getSpecialVars();
|
||||
|
||||
$dumper = new CliDumper();
|
||||
$dumper->setColors(false);
|
||||
$cloner = new VarCloner();
|
||||
|
||||
$data = $cloner->cloneVar($var);
|
||||
$out = fopen('php://memory', 'r+b');
|
||||
$dumper->dump($data, $out);
|
||||
rewind($out);
|
||||
$out = stream_get_contents($out);
|
||||
|
||||
$this->assertSame(
|
||||
<<<EOTXT
|
||||
array:2 [
|
||||
0 => array:1 [
|
||||
0 => &1 array:1 [
|
||||
0 => &1 array:1 [&1]
|
||||
]
|
||||
]
|
||||
1 => array:1 [
|
||||
"GLOBALS" => &2 array:1 [
|
||||
"GLOBALS" => &2 array:1 [&2]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
EOTXT
|
||||
,
|
||||
$out
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
*/
|
||||
public function testGlobalsNoExt()
|
||||
{
|
||||
$var = $this->getSpecialVars();
|
||||
unset($var[0]);
|
||||
$out = '';
|
||||
|
||||
$dumper = new CliDumper(function ($line, $depth) use (&$out) {
|
||||
if ($depth >= 0) {
|
||||
$out .= str_repeat(' ', $depth).$line."\n";
|
||||
}
|
||||
});
|
||||
$dumper->setColors(false);
|
||||
$cloner = new VarCloner();
|
||||
|
||||
$refl = new \ReflectionProperty($cloner, 'useExt');
|
||||
$refl->setAccessible(true);
|
||||
$refl->setValue($cloner, false);
|
||||
|
||||
$data = $cloner->cloneVar($var);
|
||||
$dumper->dump($data);
|
||||
|
||||
$this->assertSame(
|
||||
<<<EOTXT
|
||||
array:2 [
|
||||
1 => array:1 [
|
||||
"GLOBALS" => &1 array:1 [
|
||||
"GLOBALS" => &1 array:1 [&1]
|
||||
]
|
||||
]
|
||||
2 => &1 array:1 [&1]
|
||||
]
|
||||
|
||||
EOTXT
|
||||
,
|
||||
$out
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
*/
|
||||
public function testBuggyRefs()
|
||||
{
|
||||
if (PHP_VERSION_ID >= 50600) {
|
||||
$this->markTestSkipped('PHP 5.6 fixed refs counting');
|
||||
}
|
||||
|
||||
$var = $this->getSpecialVars();
|
||||
$var = $var[0];
|
||||
|
||||
$dumper = new CliDumper();
|
||||
$dumper->setColors(false);
|
||||
$cloner = new VarCloner();
|
||||
|
||||
$data = $cloner->cloneVar($var)->getLimitedClone(3, -1);
|
||||
$out = '';
|
||||
$dumper->dump($data, function ($line, $depth) use (&$out) {
|
||||
if ($depth >= 0) {
|
||||
$out .= str_repeat(' ', $depth).$line."\n";
|
||||
}
|
||||
});
|
||||
|
||||
$this->assertSame(
|
||||
<<<EOTXT
|
||||
array:1 [
|
||||
0 => array:1 [
|
||||
0 => array:1 [
|
||||
0 => array:1 [
|
||||
…1
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
EOTXT
|
||||
,
|
||||
$out
|
||||
);
|
||||
}
|
||||
|
||||
private function getSpecialVars()
|
||||
{
|
||||
foreach (array_keys($GLOBALS) as $var) {
|
||||
if ('GLOBALS' !== $var) {
|
||||
unset($GLOBALS[$var]);
|
||||
}
|
||||
}
|
||||
|
||||
$var = function &() {
|
||||
$var = array();
|
||||
$var[] =& $var;
|
||||
|
||||
return $var;
|
||||
};
|
||||
|
||||
return array($var(), $GLOBALS, &$GLOBALS);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user