[VarDumper] fix mutating $GLOBALS while cloning it

This commit is contained in:
Nicolas Grekas 2021-01-06 15:07:43 +01:00
parent 9b719ab13d
commit 384b0adf38
3 changed files with 22 additions and 14 deletions

View File

@ -335,7 +335,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
}
$cursor->hardRefTo = $refs[$r];
$cursor->hardRefHandle = $this->useRefHandles & $item->handle;
$cursor->hardRefCount = $item->refCount;
$cursor->hardRefCount = 0 < $item->handle ? $item->refCount : 0;
}
$cursor->attr = $item->attr;
$type = $item->class ?: \gettype($item->value);

View File

@ -159,13 +159,19 @@ class VarCloner extends AbstractCloner
if (Stub::ARRAY_ASSOC === $stub->class) {
// Copies of $GLOBALS have very strange behavior,
// let's detect them with some black magic
$a[$gid] = true;
// Happens with copies of $GLOBALS
if (isset($v[$gid])) {
if (\PHP_VERSION_ID < 80100 && ($a[$gid] = true) && isset($v[$gid])) {
unset($v[$gid]);
$a = [];
foreach ($v as $gk => &$gv) {
if ($v === $gv) {
unset($v);
$v = new Stub();
$v->value = [$v->cut = \count($gv), Stub::TYPE_ARRAY => 0];
$v->handle = -1;
$gv = &$hardRefs[spl_object_id($v)];
$gv = $v;
}
$a[$gk] = &$gv;
}
unset($gv);

View File

@ -439,6 +439,7 @@ EOTXT
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
* @requires PHP < 8.1
*/
public function testSpecialVars56()
{
@ -453,11 +454,11 @@ array:3 [
]
]
1 => array:1 [
"GLOBALS" => &2 array:1 [
"GLOBALS" => &2 array:1 [&2]
]
"GLOBALS" => & array:1 [ …1]
]
2 => &3 array:1 [
"GLOBALS" => &3 array:1 [&3]
]
2 => &2 array:1 [&2]
]
EOTXT
,
@ -468,6 +469,7 @@ EOTXT
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
* @requires PHP < 8.1
*/
public function testGlobals()
{
@ -490,11 +492,11 @@ EOTXT
<<<'EOTXT'
array:2 [
1 => array:1 [
"GLOBALS" => &1 array:1 [
"GLOBALS" => &1 array:1 [&1]
]
"GLOBALS" => & array:1 [ …1]
]
2 => &2 array:1 [
"GLOBALS" => &2 array:1 [&2]
]
2 => &1 array:1 [&1]
]
EOTXT
@ -584,6 +586,6 @@ EOTXT
return $var;
};
return [$var(), $GLOBALS, &$GLOBALS];
return eval('return [$var(), $GLOBALS, &$GLOBALS];');
}
}