Circular reference handling improvement

Refs https://github.com/phpseclib/phpseclib/pull/934/files#r52838650

This does the following:

* Addresses the comments to 102d53bd27

* Fixes an "Allowed memory size of ... bytes exhausted" issue and simplifies the implementation, bringing it closer to the example in https://stackoverflow.com/questions/9042142/detecting-infinite-array-recursion-in-php/9293146#9293146
This commit is contained in:
Joey3000 2016-02-14 13:40:58 +01:00
parent 102d53bd27
commit 047f2617f1

View File

@ -268,7 +268,6 @@ if (!function_exists('phpseclib_safe_serialize')) {
* PHP 5.3 will emit a warning.
*
* @param mixed $arr
* @param array $refs optional
* @access public
*/
function phpseclib_safe_serialize(&$arr)
@ -280,20 +279,16 @@ if (!function_exists('phpseclib_safe_serialize')) {
return serialize($arr);
}
$safearr = array();
$unset = false;
if (!isset($arr['__phpseclib_marker'])) {
$unset = true;
$arr['__phpseclib_marker'] = true;
}
$arr['__phpseclib_marker'] = true;
foreach (array_keys($arr) as $key) {
if (is_object($arr[$key]) || $key == '__phpseclib_marker') {
continue;
// do not recurse on:
// - the '__phpseclib_marker' key itself
// - a circular reference (marked with that key)
if ($key !== '__phpseclib_marker' && !isset($arr[$key]['__phpseclib_marker'])) {
$safearr[$key] = is_array($arr[$key]) ? phpseclib_safe_serialize($arr[$key]) : $arr[$key];
}
$safearr[$key] = is_array($arr[$key]) ? phpseclib_safe_serialize($arr[$key], $refs) : $arr[$key];
}
if ($unset) {
unset($arr['__phpseclib_marker']);
}
unset($arr['__phpseclib_marker']);
return serialize($safearr);
}
}