Merge pull request #1408 from IceCola97/PR-Branch

修复WeakRef的适配问题(<chrome84的适配问题);兼容2.4的eruda(十周年调试助手问题);兼容worker在序列化封送对象的问题(兼容皮切的worker调用);去除禁止二次传播的检查(修复联机卡死问题)
This commit is contained in:
Spmario233 2024-05-31 10:19:18 +08:00 committed by GitHub
commit 74a8c2c7ef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 105 additions and 20 deletions

View File

@ -1551,12 +1551,7 @@ export class Get {
if (func._filter_args) {
return "_noname_func:" + JSON.stringify(get.stringifiedResult(func._filter_args, 3));
}
const { Marshal, Sandbox } = security.importSandbox();
const domain = Marshal.getMarshalledDomain(func);
if (domain) {
const sandbox = Sandbox.from(domain);
if (sandbox && "client" in sandbox) throw new Error("不应该二次扩散远程代码");
}
const { Marshal } = security.importSandbox();
const str = Marshal.decompileFunction(func);
// js内置的函数
if (/\{\s*\[native code\]\s*\}/.test(str)) return "_noname_func:function () {}";

View File

@ -41,6 +41,28 @@ const SandboxSignal_ListMonitor = Symbol("ListMonitor");
const SandboxSignal_ExposeInfo = Symbol("ExposeInfo");
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
* 判断是否为基元类型
@ -914,19 +936,18 @@ class NativeWrapper {
const prototype = NativeWrapper.#currentFunction.prototype;
// 根据是否装箱进行不同的封装
const wrapped = (flags & 2)
? function (...args) {
? function (/** @type {any[]} */ ...args) {
const list = args.map(a =>
NativeWrapper.boxCallback(a, prototype));
// @ts-ignore
return ContextInvoker1(func, this, list);
}
: function (...args) {
: function (/** @type {any[]} */ ...args) {
// @ts-ignore
return ContextInvoker1(func, this, args);
};
// 构造原型链
sealObjectTree(wrapped);
Reflect.setPrototypeOf(wrapped, prototype);
return wrapped;
}
@ -945,17 +966,16 @@ class NativeWrapper {
const prototype = NativeWrapper.#currentFunction.prototype;
// 根据是否装箱进行不同的封装
const wrapped = (flags & 2)
? function (...args) {
? function (/** @type {any[]} */ ...args) {
const list = args.map(a =>
NativeWrapper.boxCallback(a, prototype));
return ContextInvoker2(func, list, new.target);
}
: function (...args) {
: function (/** @type {any[]} */ ...args) {
return ContextInvoker2(func, args, new.target);
};
// 构造原型链
sealObjectTree(wrapped);
Reflect.setPrototypeOf(wrapped, prototype);
return wrapped;
}
@ -977,7 +997,6 @@ class NativeWrapper {
};
// 构造原型链
sealObjectTree(wrapped);
Reflect.setPrototypeOf(wrapped, prototype);
return wrapped;
}
@ -993,14 +1012,13 @@ class NativeWrapper {
static wrapSetter(func) {
// @ts-ignore
const prototype = NativeWrapper.#currentFunction.prototype;
const wrapped = function (value) {
const wrapped = function (/** @type {ProxyConstructor} */ value) {
// @ts-ignore
return ContextInvoker1(func, this,
[NativeWrapper.boxCallback(value, prototype)]);
};
// 构造原型链
sealObjectTree(wrapped);
Reflect.setPrototypeOf(wrapped, prototype);
return wrapped;
}
@ -1025,7 +1043,7 @@ class NativeWrapper {
// 缓存不存在则创建
wrapped = ContextInvokerCreator({
unboxed, // 向封装函数提供unboxed函数
}, function (thiz, args, newTarget) {
}, function (/** @type {any} */ thiz, /** @type {readonly any[]} */ args, /** @type {(new (...args: any) => any) | undefined} */ newTarget) {
return newTarget
// @ts-ignore
? Reflect.construct(this.unboxed, args, newTarget)
@ -1034,13 +1052,12 @@ class NativeWrapper {
});
// 设置暴露器
wrapped[SandboxExposer] = (signal) => {
wrapped[SandboxExposer] = (/** @type {symbol} */ signal) => {
if (signal === NativeWrapper.#unboxedFunction)
return unboxed;
};
// 构造原型链
sealObjectTree(wrapped);
Reflect.setPrototypeOf(wrapped, prototype);
NativeWrapper.#boxedMap.set(unboxed, wrapped);
}
@ -1132,6 +1149,9 @@ class DomainMonitors {
return;
}
/**
* @param {{ [x: number]: Set<Monitor>; }} actionMap
*/
function addToActionMap(actionMap) {
for (const action of actions) {
let monitorMap = actionMap[action];
@ -1205,6 +1225,9 @@ class DomainMonitors {
return;
}
/**
* @param {{ [x: number]: Set<Monitor>; }} actionMap
*/
function removeFromActionMap(actionMap) {
for (const action of actions) {
const monitorMap = actionMap[action];
@ -1465,12 +1488,19 @@ class DomainMonitors {
stopPropagation() {
result.stopPropagation = true;
},
/**
* @param {string} name
* @param {any} value
*/
overrideParameter(name, value) {
if (!(name in indexMap))
throw new TypeError(`参数 ${name} 没有找到`);
args[indexMap[name]] = value;
},
/**
* @param {undefined} value
*/
setReturnValue(value) {
result.returnValue = value;
},
@ -2923,6 +2953,7 @@ class Domain {
* 确保 Array.isArray 对代理数组放宽
* ```
*
* @param {Domain} domain
* @param {any} array
* @returns {boolean}
*/
@ -3212,14 +3243,28 @@ class Sandbox {
}
const handler = {
/**
* @param {FunctionConstructor} target
* @param {any} thisArg
* @param {any[]} argArray
*/
apply(target, thisArg, argArray) {
return functionCtor(target, argArray);
},
/**
* @param {FunctionConstructor} target
* @param {any[]} argArray
* @param {any} newTarget
*/
construct(target, argArray, newTarget) {
return functionCtor(target, argArray);
},
};
/**
* @param {object} prototype
* @param {any} newCtor
*/
function rewriteCtor(prototype, newCtor) {
const descriptor = Object.getOwnPropertyDescriptor(prototype, 'constructor')
|| { configurable: true, writable: true, enumerable: false };
@ -3759,7 +3804,7 @@ class Sandbox {
Object.defineProperties(rawScope, descriptors);
}
static #makeName = function (prefix, conflict) {
static #makeName = function (/** @type {string} */ prefix, /** @type {any} */ conflict) {
let builtName;
do {
@ -3782,6 +3827,9 @@ class Sandbox {
}
}
/**
* @param {any} clazz
*/
function sealClass(clazz) {
sealObjectTree(clazz);
@ -3792,9 +3840,12 @@ function sealClass(clazz) {
}
// FREEZE FROM SOUL!
/**
* @param {any} obj
*/
function sealObjectTree(obj) {
// @ts-ignore
sealObject(obj, o => {
sealObject(obj, (/** @type {object} */ o) => {
if (!Reflect.isExtensible(o)) // 防止1103
return;
if (o === obj)
@ -3804,6 +3855,9 @@ function sealObjectTree(obj) {
});
}
/**
* @param {any} obj
*/
function sealObject(obj, freeze = Object.freeze) {
if (isPrimitive(obj))
return;

View File

@ -415,6 +415,7 @@ async function initSecurity({
return;
loadPolyfills();
initSerializeNeeded();
initIsolatedEnvironment();
// 不允许被远程代码访问的game函数
@ -810,6 +811,41 @@ function initIsolatedEnvironment() {
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
* 加载当前的垫片函数