修复WeakRef的适配问题;兼容2.4的eruda;兼容worker在序列化封送对象的问题;去除禁止二次传播的检查(修复联机卡死问题)
This commit is contained in:
parent
50083b3a07
commit
848c69386e
|
@ -1551,12 +1551,7 @@ export class Get {
|
||||||
if (func._filter_args) {
|
if (func._filter_args) {
|
||||||
return "_noname_func:" + JSON.stringify(get.stringifiedResult(func._filter_args, 3));
|
return "_noname_func:" + JSON.stringify(get.stringifiedResult(func._filter_args, 3));
|
||||||
}
|
}
|
||||||
const { Marshal, Sandbox } = security.importSandbox();
|
const { Marshal } = security.importSandbox();
|
||||||
const domain = Marshal.getMarshalledDomain(func);
|
|
||||||
if (domain) {
|
|
||||||
const sandbox = Sandbox.from(domain);
|
|
||||||
if (sandbox && "client" in sandbox) throw new Error("不应该二次扩散远程代码");
|
|
||||||
}
|
|
||||||
const str = Marshal.decompileFunction(func);
|
const str = Marshal.decompileFunction(func);
|
||||||
// js内置的函数
|
// js内置的函数
|
||||||
if (/\{\s*\[native code\]\s*\}/.test(str)) return "_noname_func:function () {}";
|
if (/\{\s*\[native code\]\s*\}/.test(str)) return "_noname_func:function () {}";
|
||||||
|
|
|
@ -41,6 +41,28 @@ const SandboxSignal_ListMonitor = Symbol("ListMonitor");
|
||||||
const SandboxSignal_ExposeInfo = Symbol("ExposeInfo");
|
const SandboxSignal_ExposeInfo = Symbol("ExposeInfo");
|
||||||
const SandboxSignal_TryFunctionRefs = Symbol("TryFunctionRefs");
|
const SandboxSignal_TryFunctionRefs = Symbol("TryFunctionRefs");
|
||||||
|
|
||||||
|
// 用于适配 < Chrome 84 的设备
|
||||||
|
const WeakRef = window.WeakRef || class WeakRef {
|
||||||
|
/**
|
||||||
|
* @param {any} target
|
||||||
|
*/
|
||||||
|
constructor(target) {
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {any}
|
||||||
|
*/
|
||||||
|
deref() {
|
||||||
|
return this.target;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {"WeakRef"}
|
||||||
|
*/
|
||||||
|
[Symbol.toStringTag] = "WeakRef";
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ```plain
|
* ```plain
|
||||||
* 判断是否为基元类型
|
* 判断是否为基元类型
|
||||||
|
@ -914,19 +936,18 @@ class NativeWrapper {
|
||||||
const prototype = NativeWrapper.#currentFunction.prototype;
|
const prototype = NativeWrapper.#currentFunction.prototype;
|
||||||
// 根据是否装箱进行不同的封装
|
// 根据是否装箱进行不同的封装
|
||||||
const wrapped = (flags & 2)
|
const wrapped = (flags & 2)
|
||||||
? function (...args) {
|
? function (/** @type {any[]} */ ...args) {
|
||||||
const list = args.map(a =>
|
const list = args.map(a =>
|
||||||
NativeWrapper.boxCallback(a, prototype));
|
NativeWrapper.boxCallback(a, prototype));
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return ContextInvoker1(func, this, list);
|
return ContextInvoker1(func, this, list);
|
||||||
}
|
}
|
||||||
: function (...args) {
|
: function (/** @type {any[]} */ ...args) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return ContextInvoker1(func, this, args);
|
return ContextInvoker1(func, this, args);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 构造原型链
|
// 构造原型链
|
||||||
sealObjectTree(wrapped);
|
|
||||||
Reflect.setPrototypeOf(wrapped, prototype);
|
Reflect.setPrototypeOf(wrapped, prototype);
|
||||||
return wrapped;
|
return wrapped;
|
||||||
}
|
}
|
||||||
|
@ -945,17 +966,16 @@ class NativeWrapper {
|
||||||
const prototype = NativeWrapper.#currentFunction.prototype;
|
const prototype = NativeWrapper.#currentFunction.prototype;
|
||||||
// 根据是否装箱进行不同的封装
|
// 根据是否装箱进行不同的封装
|
||||||
const wrapped = (flags & 2)
|
const wrapped = (flags & 2)
|
||||||
? function (...args) {
|
? function (/** @type {any[]} */ ...args) {
|
||||||
const list = args.map(a =>
|
const list = args.map(a =>
|
||||||
NativeWrapper.boxCallback(a, prototype));
|
NativeWrapper.boxCallback(a, prototype));
|
||||||
return ContextInvoker2(func, list, new.target);
|
return ContextInvoker2(func, list, new.target);
|
||||||
}
|
}
|
||||||
: function (...args) {
|
: function (/** @type {any[]} */ ...args) {
|
||||||
return ContextInvoker2(func, args, new.target);
|
return ContextInvoker2(func, args, new.target);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 构造原型链
|
// 构造原型链
|
||||||
sealObjectTree(wrapped);
|
|
||||||
Reflect.setPrototypeOf(wrapped, prototype);
|
Reflect.setPrototypeOf(wrapped, prototype);
|
||||||
return wrapped;
|
return wrapped;
|
||||||
}
|
}
|
||||||
|
@ -977,7 +997,6 @@ class NativeWrapper {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 构造原型链
|
// 构造原型链
|
||||||
sealObjectTree(wrapped);
|
|
||||||
Reflect.setPrototypeOf(wrapped, prototype);
|
Reflect.setPrototypeOf(wrapped, prototype);
|
||||||
return wrapped;
|
return wrapped;
|
||||||
}
|
}
|
||||||
|
@ -993,14 +1012,13 @@ class NativeWrapper {
|
||||||
static wrapSetter(func) {
|
static wrapSetter(func) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const prototype = NativeWrapper.#currentFunction.prototype;
|
const prototype = NativeWrapper.#currentFunction.prototype;
|
||||||
const wrapped = function (value) {
|
const wrapped = function (/** @type {ProxyConstructor} */ value) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return ContextInvoker1(func, this,
|
return ContextInvoker1(func, this,
|
||||||
[NativeWrapper.boxCallback(value, prototype)]);
|
[NativeWrapper.boxCallback(value, prototype)]);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 构造原型链
|
// 构造原型链
|
||||||
sealObjectTree(wrapped);
|
|
||||||
Reflect.setPrototypeOf(wrapped, prototype);
|
Reflect.setPrototypeOf(wrapped, prototype);
|
||||||
return wrapped;
|
return wrapped;
|
||||||
}
|
}
|
||||||
|
@ -1025,7 +1043,7 @@ class NativeWrapper {
|
||||||
// 缓存不存在则创建
|
// 缓存不存在则创建
|
||||||
wrapped = ContextInvokerCreator({
|
wrapped = ContextInvokerCreator({
|
||||||
unboxed, // 向封装函数提供unboxed函数
|
unboxed, // 向封装函数提供unboxed函数
|
||||||
}, function (thiz, args, newTarget) {
|
}, function (/** @type {any} */ thiz, /** @type {readonly any[]} */ args, /** @type {(new (...args: any) => any) | undefined} */ newTarget) {
|
||||||
return newTarget
|
return newTarget
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
? Reflect.construct(this.unboxed, args, newTarget)
|
? Reflect.construct(this.unboxed, args, newTarget)
|
||||||
|
@ -1034,13 +1052,12 @@ class NativeWrapper {
|
||||||
});
|
});
|
||||||
|
|
||||||
// 设置暴露器
|
// 设置暴露器
|
||||||
wrapped[SandboxExposer] = (signal) => {
|
wrapped[SandboxExposer] = (/** @type {symbol} */ signal) => {
|
||||||
if (signal === NativeWrapper.#unboxedFunction)
|
if (signal === NativeWrapper.#unboxedFunction)
|
||||||
return unboxed;
|
return unboxed;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 构造原型链
|
// 构造原型链
|
||||||
sealObjectTree(wrapped);
|
|
||||||
Reflect.setPrototypeOf(wrapped, prototype);
|
Reflect.setPrototypeOf(wrapped, prototype);
|
||||||
NativeWrapper.#boxedMap.set(unboxed, wrapped);
|
NativeWrapper.#boxedMap.set(unboxed, wrapped);
|
||||||
}
|
}
|
||||||
|
@ -1132,6 +1149,9 @@ class DomainMonitors {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {{ [x: number]: Set<Monitor>; }} actionMap
|
||||||
|
*/
|
||||||
function addToActionMap(actionMap) {
|
function addToActionMap(actionMap) {
|
||||||
for (const action of actions) {
|
for (const action of actions) {
|
||||||
let monitorMap = actionMap[action];
|
let monitorMap = actionMap[action];
|
||||||
|
@ -1205,6 +1225,9 @@ class DomainMonitors {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {{ [x: number]: Set<Monitor>; }} actionMap
|
||||||
|
*/
|
||||||
function removeFromActionMap(actionMap) {
|
function removeFromActionMap(actionMap) {
|
||||||
for (const action of actions) {
|
for (const action of actions) {
|
||||||
const monitorMap = actionMap[action];
|
const monitorMap = actionMap[action];
|
||||||
|
@ -1465,12 +1488,19 @@ class DomainMonitors {
|
||||||
stopPropagation() {
|
stopPropagation() {
|
||||||
result.stopPropagation = true;
|
result.stopPropagation = true;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* @param {string} name
|
||||||
|
* @param {any} value
|
||||||
|
*/
|
||||||
overrideParameter(name, value) {
|
overrideParameter(name, value) {
|
||||||
if (!(name in indexMap))
|
if (!(name in indexMap))
|
||||||
throw new TypeError(`参数 ${name} 没有找到`);
|
throw new TypeError(`参数 ${name} 没有找到`);
|
||||||
|
|
||||||
args[indexMap[name]] = value;
|
args[indexMap[name]] = value;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* @param {undefined} value
|
||||||
|
*/
|
||||||
setReturnValue(value) {
|
setReturnValue(value) {
|
||||||
result.returnValue = value;
|
result.returnValue = value;
|
||||||
},
|
},
|
||||||
|
@ -2923,6 +2953,7 @@ class Domain {
|
||||||
* 确保 Array.isArray 对代理数组放宽
|
* 确保 Array.isArray 对代理数组放宽
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
|
* @param {Domain} domain
|
||||||
* @param {any} array
|
* @param {any} array
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
|
@ -3212,14 +3243,28 @@ class Sandbox {
|
||||||
}
|
}
|
||||||
|
|
||||||
const handler = {
|
const handler = {
|
||||||
|
/**
|
||||||
|
* @param {FunctionConstructor} target
|
||||||
|
* @param {any} thisArg
|
||||||
|
* @param {any[]} argArray
|
||||||
|
*/
|
||||||
apply(target, thisArg, argArray) {
|
apply(target, thisArg, argArray) {
|
||||||
return functionCtor(target, argArray);
|
return functionCtor(target, argArray);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* @param {FunctionConstructor} target
|
||||||
|
* @param {any[]} argArray
|
||||||
|
* @param {any} newTarget
|
||||||
|
*/
|
||||||
construct(target, argArray, newTarget) {
|
construct(target, argArray, newTarget) {
|
||||||
return functionCtor(target, argArray);
|
return functionCtor(target, argArray);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {object} prototype
|
||||||
|
* @param {any} newCtor
|
||||||
|
*/
|
||||||
function rewriteCtor(prototype, newCtor) {
|
function rewriteCtor(prototype, newCtor) {
|
||||||
const descriptor = Object.getOwnPropertyDescriptor(prototype, 'constructor')
|
const descriptor = Object.getOwnPropertyDescriptor(prototype, 'constructor')
|
||||||
|| { configurable: true, writable: true, enumerable: false };
|
|| { configurable: true, writable: true, enumerable: false };
|
||||||
|
@ -3759,7 +3804,7 @@ class Sandbox {
|
||||||
Object.defineProperties(rawScope, descriptors);
|
Object.defineProperties(rawScope, descriptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
static #makeName = function (prefix, conflict) {
|
static #makeName = function (/** @type {string} */ prefix, /** @type {any} */ conflict) {
|
||||||
let builtName;
|
let builtName;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -3782,6 +3827,9 @@ class Sandbox {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {any} clazz
|
||||||
|
*/
|
||||||
function sealClass(clazz) {
|
function sealClass(clazz) {
|
||||||
sealObjectTree(clazz);
|
sealObjectTree(clazz);
|
||||||
|
|
||||||
|
@ -3792,9 +3840,12 @@ function sealClass(clazz) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FREEZE FROM SOUL!
|
// FREEZE FROM SOUL!
|
||||||
|
/**
|
||||||
|
* @param {any} obj
|
||||||
|
*/
|
||||||
function sealObjectTree(obj) {
|
function sealObjectTree(obj) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
sealObject(obj, o => {
|
sealObject(obj, (/** @type {object} */ o) => {
|
||||||
if (!Reflect.isExtensible(o)) // 防止1103
|
if (!Reflect.isExtensible(o)) // 防止1103
|
||||||
return;
|
return;
|
||||||
if (o === obj)
|
if (o === obj)
|
||||||
|
@ -3804,6 +3855,9 @@ function sealObjectTree(obj) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {any} obj
|
||||||
|
*/
|
||||||
function sealObject(obj, freeze = Object.freeze) {
|
function sealObject(obj, freeze = Object.freeze) {
|
||||||
if (isPrimitive(obj))
|
if (isPrimitive(obj))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -415,6 +415,7 @@ async function initSecurity({
|
||||||
return;
|
return;
|
||||||
|
|
||||||
loadPolyfills();
|
loadPolyfills();
|
||||||
|
initSerializeNeeded();
|
||||||
initIsolatedEnvironment();
|
initIsolatedEnvironment();
|
||||||
|
|
||||||
// 不允许被远程代码访问的game函数
|
// 不允许被远程代码访问的game函数
|
||||||
|
@ -810,6 +811,41 @@ function initIsolatedEnvironment() {
|
||||||
rewriteCtor(defaultAsyncGeneratorFunction.prototype, ModAsyncGeneratorFunction);
|
rewriteCtor(defaultAsyncGeneratorFunction.prototype, ModAsyncGeneratorFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ```plain
|
||||||
|
* 初始化需要额外序列化的函数
|
||||||
|
*
|
||||||
|
* 适配扩展,当在skillcontent里面调用皮切的playEffect时会报错
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
function initSerializeNeeded() {
|
||||||
|
const structuredClone = window.structuredClone;
|
||||||
|
const deepClone = (/** @type {any} */ obj) => {
|
||||||
|
try {
|
||||||
|
return structuredClone(obj);
|
||||||
|
} catch (e) {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @type {Array<[string, number[]]>} */
|
||||||
|
const funcList = [
|
||||||
|
["Worker.prototype.postMessage", [0]],
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const [funcCode, argIndexes] of funcList) {
|
||||||
|
const originalFunc = new Function(`return ${funcCode}`)();
|
||||||
|
const newFunc = /** @this {any} */ function (/** @type {any[]} */ ...args) {
|
||||||
|
for (const index of argIndexes)
|
||||||
|
args[index] = deepClone(args[index]);
|
||||||
|
|
||||||
|
return originalFunc.apply(this, args);
|
||||||
|
};
|
||||||
|
|
||||||
|
new Function("_", `${funcCode} = _;`)(newFunc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ```plain
|
* ```plain
|
||||||
* 加载当前的垫片函数
|
* 加载当前的垫片函数
|
||||||
|
|
Loading…
Reference in New Issue