[VarDumper] Fix "next element is already occupied"

This commit is contained in:
Nicolas Grekas 2015-03-06 17:45:31 +01:00
parent 700447df8d
commit 32a81f79aa
2 changed files with 53 additions and 5 deletions

View File

@ -38,8 +38,9 @@ class VarCloner extends AbstractCloner
$maxItems = $this->maxItems;
$maxString = $this->maxString;
$cookie = (object) array(); // Unique object used to detect hard references
$gid = uniqid(mt_rand(), true); // Unique string used to detect the special $GLOBALS variable
$a = null; // Array cast for nested structures
$stub = null; // Stub capturing the main properties of an original item value,
$stub = null; // Stub capturing the main properties of an original item value
// or null if the original value is used directly
$zval = array( // Main properties of the current value
'type' => null,
@ -121,16 +122,20 @@ class VarCloner extends AbstractCloner
$stub->value = $zval['array_count'] ?: count($v);
$a = $v;
$a[] = null;
$h = count($v);
array_pop($a);
// Copies of $GLOBALS have very strange behavior,
// let's detect them with some black magic
$a[$gid] = true;
// Happens with copies of $GLOBALS
if ($h !== $stub->value) {
if (isset($v[$gid])) {
unset($v[$gid]);
$a = array();
foreach ($v as $gk => &$gv) {
$a[$gk] =& $gv;
}
} else {
$a = $v;
}
}
break;

View File

@ -18,6 +18,49 @@ use Symfony\Component\VarDumper\Cloner\VarCloner;
*/
class VarClonerTest extends \PHPUnit_Framework_TestCase
{
public function testMaxIntBoundary()
{
$data = array(PHP_INT_MAX => 123);
$cloner = new VarCloner();
$clone = $cloner->cloneVar($data);
$expected = <<<EOTXT
Symfony\Component\VarDumper\Cloner\Data Object
(
[data:Symfony\Component\VarDumper\Cloner\Data:private] => Array
(
[0] => Array
(
[0] => Symfony\Component\VarDumper\Cloner\Stub Object
(
[type] => array
[class] => assoc
[value] => 1
[cut] => 0
[handle] => 0
[refCount] => 0
[position] => 1
)
)
[1] => Array
(
[%s] => 123
)
)
[maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20
[maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1
[useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1
)
EOTXT;
$this->assertSame(sprintf($expected, PHP_INT_MAX), print_r($clone, true));
}
public function testClone()
{
$json = json_decode('{"1":{"var":"val"},"2":{"var":"val"}}');