防止资源比较循环递归溢出
为 sameResource 增加对象对访问跟踪,遇到循环结构时安全终止递归
This commit is contained in:
@@ -238,7 +238,11 @@ function cloneState(state: State): State {
|
||||
return structuredClone(state);
|
||||
}
|
||||
|
||||
function sameResource<T>(left: T, right: T): boolean {
|
||||
function sameResource<T>(
|
||||
left: T,
|
||||
right: T,
|
||||
seenPairs = new WeakMap<object, WeakSet<object>>(),
|
||||
): boolean {
|
||||
if (Object.is(left, right)) return true;
|
||||
if (
|
||||
typeof left !== 'object' ||
|
||||
@@ -248,10 +252,22 @@ function sameResource<T>(left: T, right: T): boolean {
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
const leftObject = left as object;
|
||||
const rightObject = right as object;
|
||||
let seenRightObjects = seenPairs.get(leftObject);
|
||||
if (seenRightObjects?.has(rightObject)) return true;
|
||||
if (!seenRightObjects) {
|
||||
seenRightObjects = new WeakSet<object>();
|
||||
seenPairs.set(leftObject, seenRightObjects);
|
||||
}
|
||||
seenRightObjects.add(rightObject);
|
||||
|
||||
if (Array.isArray(left) || Array.isArray(right)) {
|
||||
if (!Array.isArray(left) || !Array.isArray(right)) return false;
|
||||
if (left.length !== right.length) return false;
|
||||
return left.every((value, index) => sameResource(value, right[index]));
|
||||
return left.every((value, index) =>
|
||||
sameResource(value, right[index], seenPairs),
|
||||
);
|
||||
}
|
||||
const leftRecord = left as Record<string, unknown>;
|
||||
const rightRecord = right as Record<string, unknown>;
|
||||
@@ -261,7 +277,7 @@ function sameResource<T>(left: T, right: T): boolean {
|
||||
return leftKeys.every(
|
||||
(key) =>
|
||||
Object.prototype.hasOwnProperty.call(rightRecord, key) &&
|
||||
sameResource(leftRecord[key], rightRecord[key]),
|
||||
sameResource(leftRecord[key], rightRecord[key], seenPairs),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user