修复联机bug;去除部分debugger
This commit is contained in:
parent
271b8039a4
commit
7c0fa0b02e
|
@ -57,7 +57,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
|
|||
game.saveConfig("last_ip", ip);
|
||||
game.connect(ip, function (success) {
|
||||
if (success) {
|
||||
game.requireSandboxOn(ip); // 启用沙盒喵
|
||||
game.requireSandboxOn(ip);
|
||||
var info = lib.config.reconnect_info;
|
||||
if (info && info[0] == _status.ip) {
|
||||
game.onlineID = info[1];
|
||||
|
|
|
@ -1346,7 +1346,7 @@ export class Game {
|
|||
* @param {*} message
|
||||
*/
|
||||
sendTo(id, message) {
|
||||
return new lib.element.Client(new lib.element.NodeWS(id)).send(message);
|
||||
return new lib.element.Client(new lib.element.NodeWS(id), true).send(message);
|
||||
}
|
||||
createServer() {
|
||||
lib.node.clients = [];
|
||||
|
|
|
@ -1521,7 +1521,9 @@ export class Get {
|
|||
str = str.trim();
|
||||
const arrowMatch = get.#arrowPattern.exec(str);
|
||||
if (arrowMatch) {
|
||||
const body = `return ${str.slice(arrowMatch[0].length)}`;
|
||||
let body = str.slice(arrowMatch[0].length).trim();
|
||||
if (body.startsWith("{") && body.endsWith("}")) body = body.slice(1, -1);
|
||||
else body = `return ${body}`;
|
||||
if (!get.isFunctionBody(body)) {
|
||||
console.error("发现疑似恶意的远程代码:", str);
|
||||
return `()=>console.error("尝试执行疑似恶意的远程代码")`;
|
||||
|
@ -1558,7 +1560,9 @@ export class Get {
|
|||
}
|
||||
infoFuncOL(info) {
|
||||
let func;
|
||||
console.log("[infoFuncOL] info:", info);
|
||||
const str = get.pureFunctionStr(info.slice(13)); // 清洗函数并阻止注入
|
||||
console.log("[infoFuncOL] pured:", str);
|
||||
try {
|
||||
// js内置的函数
|
||||
if (/\{\s*\[native code\]\s*\}/.test(str)) return function () { };
|
||||
|
|
|
@ -128,13 +128,6 @@ export async function boot() {
|
|||
// 初始化沙盒的Realms
|
||||
await initializeSandboxRealms();
|
||||
|
||||
// 初始化security
|
||||
const securityModule = await import("../util/security.js");
|
||||
const security = securityModule.default;
|
||||
security.initSecurity({
|
||||
lib, game, ui, get, ai, _status, gnc,
|
||||
});
|
||||
|
||||
// 设定游戏加载时间,超过时间未加载就提醒
|
||||
const configLoadTime = localStorage.getItem(lib.configprefix + "loadtime");
|
||||
// 现在不暴露到全局变量里了,直接传给onload
|
||||
|
@ -243,6 +236,7 @@ export async function boot() {
|
|||
await window.initReadWriteFunction(g).catch((e) => {
|
||||
console.error("文件读写函数初始化失败:", e);
|
||||
});
|
||||
delete window.initReadWriteFunction; // 后续用不到了喵
|
||||
}
|
||||
window.onbeforeunload = function () {
|
||||
if (config.get("confirm_exit") && !_status.reloading) {
|
||||
|
@ -254,6 +248,13 @@ export async function boot() {
|
|||
}
|
||||
}
|
||||
|
||||
// 初始化security
|
||||
const securityModule = await import("../util/security.js");
|
||||
const security = securityModule.default;
|
||||
security.initSecurity({
|
||||
lib, game, ui, get, ai, _status, gnc,
|
||||
});
|
||||
|
||||
const loadCssPromise = loadCss();
|
||||
const loadConfigPromise = loadConfig();
|
||||
await loadCssPromise;
|
||||
|
@ -489,8 +490,7 @@ export async function boot() {
|
|||
//var backup_onload=lib.init.onload;
|
||||
_status.evaluatingExtension = true;
|
||||
try {
|
||||
debugger; // NEED TO VIEW DATA
|
||||
security.eval(extcontent);
|
||||
security.eval(extcontent); // 喵?
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ export class Client {
|
|||
/**
|
||||
* @param {import('../index.js').NodeWS | InstanceType<typeof import('ws').WebSocket> | Client} ws
|
||||
*/
|
||||
constructor(ws) {
|
||||
constructor(ws, temp) {
|
||||
if (ws instanceof Client) throw new Error("Client cannot copy.");
|
||||
this.ws = ws;
|
||||
/**
|
||||
|
@ -18,7 +18,9 @@ export class Client {
|
|||
// @ts-ignore
|
||||
this.id = ws.wsid || get.id();
|
||||
this.closed = false;
|
||||
this.sandbox = security.createSandbox();
|
||||
|
||||
if (!temp)
|
||||
this.sandbox = security.createSandbox();
|
||||
}
|
||||
send() {
|
||||
if (this.closed) return this;
|
||||
|
|
|
@ -306,14 +306,14 @@ export class Library {
|
|||
typeof yingbianZhuzhanAI == "function"
|
||||
? yingbianZhuzhanAI(player, card, source, targets)
|
||||
: cardx => {
|
||||
var info = get.info(card);
|
||||
if (info && info.ai && info.ai.yingbian) {
|
||||
var ai = info.ai.yingbian(card, source, targets, player);
|
||||
if (!ai) return 0;
|
||||
return ai - get.value(cardx);
|
||||
} else if (get.attitude(player, source) <= 0) return 0;
|
||||
return 5 - get.value(cardx);
|
||||
},
|
||||
var info = get.info(card);
|
||||
if (info && info.ai && info.ai.yingbian) {
|
||||
var ai = info.ai.yingbian(card, source, targets, player);
|
||||
if (!ai) return 0;
|
||||
return ai - get.value(cardx);
|
||||
} else if (get.attitude(player, source) <= 0) return 0;
|
||||
return 5 - get.value(cardx);
|
||||
},
|
||||
});
|
||||
if (!game.online) return;
|
||||
_status.event._resultid = id;
|
||||
|
@ -6334,7 +6334,6 @@ export class Library {
|
|||
code = container.textarea.value;
|
||||
}
|
||||
try {
|
||||
debugger; // NEED TO VIEW DATA
|
||||
var { character } = security.exec2(code);
|
||||
if (!Array.isArray(character)) {
|
||||
throw "err";
|
||||
|
@ -6422,7 +6421,6 @@ export class Library {
|
|||
code = container.textarea.value;
|
||||
}
|
||||
try {
|
||||
debugger; // NEED TO VIEW DATA
|
||||
var { character } = security.exec2(code);
|
||||
if (!Array.isArray(character)) {
|
||||
throw "err";
|
||||
|
@ -6851,7 +6849,6 @@ export class Library {
|
|||
code = container.textarea.value;
|
||||
}
|
||||
try {
|
||||
debugger; // NEED TO VIEW DATA
|
||||
var { character } = security.exec2(code);
|
||||
if (!get.is.object(character)) {
|
||||
throw "err";
|
||||
|
@ -7753,8 +7750,10 @@ export class Library {
|
|||
if (Array.isArray(context)) {
|
||||
try {
|
||||
const code = context.length == 1 ? context[0].string : context.reduceRight((pre, cur) => (pre.string || pre) + "." + cur.string);
|
||||
debugger; // NEED TO VIEW DATA
|
||||
obj = security.eval(`return ${code};`);
|
||||
obj = security.exec(`return ${code};`, {
|
||||
event, trigger, player, card, cards,
|
||||
result, source, target, targets,
|
||||
});
|
||||
if (![null, undefined].includes(obj)) {
|
||||
const keys = Object.getOwnPropertyNames(obj)
|
||||
.concat(Object.getOwnPropertyNames(Object.getPrototypeOf(obj)))
|
||||
|
@ -8042,10 +8041,10 @@ export class Library {
|
|||
genAwait(item) {
|
||||
return gnc.is.generator(item)
|
||||
? gnc.of(function* () {
|
||||
for (const content of item) {
|
||||
yield content;
|
||||
}
|
||||
})()
|
||||
for (const content of item) {
|
||||
yield content;
|
||||
}
|
||||
})()
|
||||
: Promise.resolve(item);
|
||||
}
|
||||
gnc = {
|
||||
|
@ -10622,16 +10621,16 @@ export class Library {
|
|||
const cardName = get.name(cards[0], player);
|
||||
return cardName
|
||||
? new lib.element.VCard({
|
||||
name: cardName,
|
||||
nature: get.nature(cards[0], player),
|
||||
suit: get.suit(cards[0], player),
|
||||
number: get.number(cards[0], player),
|
||||
isCard: true,
|
||||
cards: [cards[0]],
|
||||
storage: {
|
||||
stratagem_buffed: 1,
|
||||
},
|
||||
})
|
||||
name: cardName,
|
||||
nature: get.nature(cards[0], player),
|
||||
suit: get.suit(cards[0], player),
|
||||
number: get.number(cards[0], player),
|
||||
isCard: true,
|
||||
cards: [cards[0]],
|
||||
storage: {
|
||||
stratagem_buffed: 1,
|
||||
},
|
||||
})
|
||||
: new lib.element.VCard();
|
||||
}
|
||||
return null;
|
||||
|
@ -12260,7 +12259,6 @@ export class Library {
|
|||
log: function () {
|
||||
var items = [];
|
||||
try {
|
||||
debugger; // NEED TO VIEW DATA
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
items.push(security.eval(`return ${arguments[i]}`));
|
||||
}
|
||||
|
@ -12531,7 +12529,7 @@ export class Library {
|
|||
navigator.clipboard
|
||||
.readText()
|
||||
.then(read)
|
||||
.catch(_ => {});
|
||||
.catch(_ => { });
|
||||
} else {
|
||||
var input = ui.create.node("textarea", ui.window, { opacity: "0" });
|
||||
input.select();
|
||||
|
|
|
@ -293,7 +293,6 @@ export class LibInit {
|
|||
if (data.includes("sojson") || data.includes("jsjiami") || data.includes("var _0x")) alert(`检测到您安装了使用免费版sojson进行加密的扩展。请谨慎使用这些扩展,避免游戏数据遭到破坏。\n扩展文件:${pathToRead}`);
|
||||
}
|
||||
try {
|
||||
debugger; // NEED TO VIEW DATA
|
||||
security.eval(data);
|
||||
if (typeof onLoad == "function") onLoad();
|
||||
} catch (error) {
|
||||
|
@ -775,7 +774,6 @@ export class LibInit {
|
|||
|
||||
eval(func) {
|
||||
if (typeof func == "function") {
|
||||
debugger; // NEED TO VIEW DATA
|
||||
return security.eval(`return (${func.toString()});`);
|
||||
} else if (typeof func == "object") {
|
||||
for (var i in func) {
|
||||
|
@ -783,7 +781,6 @@ export class LibInit {
|
|||
if (typeof func[i] == "function") {
|
||||
let checkObject = {};
|
||||
checkObject[i] = func[i];
|
||||
debugger; // NEED TO VIEW DATA
|
||||
return security.eval(`return ${get.stringify(checkObject)};`)[i];
|
||||
} else {
|
||||
func[i] = lib.init.eval(func[i]);
|
||||
|
|
|
@ -1679,7 +1679,6 @@ export const extensionMenu = function (connectMenu) {
|
|||
code = container.textarea.value;
|
||||
}
|
||||
try {
|
||||
debugger; // NEED TO VIEW DATA
|
||||
var { card } = security.exec2(code);
|
||||
if (card == null || typeof card != "object") {
|
||||
throw "err";
|
||||
|
@ -1769,7 +1768,6 @@ export const extensionMenu = function (connectMenu) {
|
|||
page.content.pack.translate[name] = translate;
|
||||
page.content.pack.translate[name + "_info"] = info;
|
||||
try {
|
||||
debugger; // NEED TO VIEW DATA
|
||||
var { card } = security.exec2(container.code);
|
||||
if (card == null || typeof card != "object") {
|
||||
throw "err";
|
||||
|
@ -2138,7 +2136,6 @@ export const extensionMenu = function (connectMenu) {
|
|||
code = container.textarea.value;
|
||||
}
|
||||
try {
|
||||
debugger; // NEED TO VIEW DATA
|
||||
var { skill } = security.exec2(code);
|
||||
if (skill == null || typeof skill != "object") {
|
||||
throw "err";
|
||||
|
@ -2321,7 +2318,6 @@ export const extensionMenu = function (connectMenu) {
|
|||
page.content.pack.translate[name] = translate;
|
||||
page.content.pack.translate[name + "_info"] = info;
|
||||
try {
|
||||
debugger; // NEED TO VIEW DATA
|
||||
var { skill } = security.exec2(container.code);
|
||||
if (skill == null || typeof skill != "object") {
|
||||
throw "err";
|
||||
|
@ -2452,19 +2448,16 @@ export const extensionMenu = function (connectMenu) {
|
|||
}
|
||||
try {
|
||||
if (link == "content" || link == "precontent") {
|
||||
debugger; // NEED TO VIEW DATA
|
||||
var { func } = security.exec2(`func = ${code}`);
|
||||
if (typeof func != "function") {
|
||||
throw "err";
|
||||
}
|
||||
} else if (link == "config") {
|
||||
debugger; // NEED TO VIEW DATA
|
||||
var { config } = security.exec2(code);
|
||||
if (config == null || typeof config != "object") {
|
||||
throw "err";
|
||||
}
|
||||
} else if (link == "help") {
|
||||
debugger; // NEED TO VIEW DATA
|
||||
var { help } = security.exec2(code);
|
||||
if (help == null || typeof help != "object") {
|
||||
throw "err";
|
||||
|
@ -2906,13 +2899,12 @@ export const extensionMenu = function (connectMenu) {
|
|||
}
|
||||
}
|
||||
};
|
||||
debugger; // NEED TO VIEW DATA
|
||||
window.extension = {};
|
||||
fetch(`${extensionURL}catalog.js`, {
|
||||
referrerPolicy: "no-referrer",
|
||||
})
|
||||
.then((response) => response.text())
|
||||
.then(security.eval)
|
||||
.then(security.eval) // 返回的是HTML?
|
||||
.then(loaded)
|
||||
.catch((reason) => {
|
||||
console.log(reason);
|
||||
|
|
|
@ -97,10 +97,6 @@ async function initializeSandboxRealms() {
|
|||
iframe.contentWindow.document.head.appendChild(script);
|
||||
await promise; // Top Await Required Chrome 89
|
||||
|
||||
// @ts-ignore
|
||||
if (!iframe.contentWindow.SANDBOX_EXPORT)
|
||||
throw new ReferenceError("无法同步载入运行域");
|
||||
|
||||
// @ts-ignore
|
||||
delete iframe.contentWindow.replacedGlobal;
|
||||
// @ts-ignore
|
||||
|
|
|
@ -316,7 +316,7 @@ class Rule {
|
|||
* 返回值则控制本次访问是否允许
|
||||
* ```
|
||||
*
|
||||
* @param {(...args: any[]) => boolean} accessControl
|
||||
* @param {(action: number, ...args: any[]) => boolean} accessControl
|
||||
*/
|
||||
setAccessControl(accessControl) {
|
||||
Rule.#assertOperator(this);
|
||||
|
@ -442,6 +442,7 @@ const MARSHALLED_LIST = Object.freeze([
|
|||
"/requestIdleCallback",
|
||||
"/cancelIdleCallback",
|
||||
"/queueMicrotask",
|
||||
"/MutationObserver",
|
||||
]);
|
||||
|
||||
/**
|
||||
|
@ -2146,7 +2147,7 @@ class Marshal {
|
|||
|
||||
if (rule && !rule.canAccess(AccessAction.CALL,
|
||||
target, marshalledThis, marshalledArgs))
|
||||
throw new ReferenceError("Access denied");
|
||||
throw new ReferenceError("封送对象的源运行域禁止了此项操作");
|
||||
|
||||
const args = [target, marshalledThis, marshalledArgs];
|
||||
const dispatched = DomainMonitors.dispatch(
|
||||
|
@ -2177,7 +2178,7 @@ class Marshal {
|
|||
|
||||
if (rule && !rule.canAccess(AccessAction.NEW,
|
||||
target, argArray, newTarget))
|
||||
throw new ReferenceError("Access denied");
|
||||
throw new ReferenceError("封送对象的源运行域禁止了此项操作");
|
||||
|
||||
const args = [target, marshalledArgs, marshalledNewTarget];
|
||||
const dispatched = DomainMonitors.dispatch(
|
||||
|
@ -2227,7 +2228,7 @@ class Marshal {
|
|||
|
||||
if (rule && !rule.canAccess(AccessAction.DEFINE,
|
||||
target, property, attributes))
|
||||
throw new ReferenceError("Access denied");
|
||||
throw new ReferenceError("封送对象的源运行域禁止了此项操作");
|
||||
|
||||
const args = [target, property, attributes];
|
||||
const dispatched = DomainMonitors.dispatch(
|
||||
|
@ -2251,7 +2252,7 @@ class Marshal {
|
|||
const rule = ruleRef.rule;
|
||||
|
||||
if (rule && !rule.canAccess(AccessAction.DELETE, target, p))
|
||||
throw new ReferenceError("Access denied");
|
||||
throw new ReferenceError("封送对象的源运行域禁止了此项操作");
|
||||
|
||||
const args = [target, p];
|
||||
const dispatched = DomainMonitors.dispatch(
|
||||
|
@ -2286,7 +2287,7 @@ class Marshal {
|
|||
|
||||
if (rule && !rule.canAccess(AccessAction.READ,
|
||||
target, p, marshalledReceiver))
|
||||
throw new ReferenceError("Access denied");
|
||||
throw new ReferenceError("封送对象的源运行域禁止了此项操作");
|
||||
|
||||
// 通知 Monitor
|
||||
const args = [target, p, marshalledReceiver];
|
||||
|
@ -2310,7 +2311,7 @@ class Marshal {
|
|||
const rule = ruleRef.rule;
|
||||
|
||||
if (rule && !rule.canAccess(AccessAction.DESCRIBE, target, p))
|
||||
throw new ReferenceError("Access denied");
|
||||
throw new ReferenceError("封送对象的源运行域禁止了此项操作");
|
||||
|
||||
const args = [target, p];
|
||||
const dispatched = DomainMonitors.dispatch(
|
||||
|
@ -2336,7 +2337,7 @@ class Marshal {
|
|||
const rule = ruleRef.rule;
|
||||
|
||||
if (rule && !rule.canAccess(AccessAction.TRACE, target))
|
||||
throw new ReferenceError("Access denied");
|
||||
throw new ReferenceError("封送对象的源运行域禁止了此项操作");
|
||||
|
||||
const args = [target];
|
||||
const dispatched = DomainMonitors.dispatch(
|
||||
|
@ -2361,7 +2362,7 @@ class Marshal {
|
|||
const rule = ruleRef.rule;
|
||||
|
||||
if (rule && !rule.canAccess(AccessAction.EXISTS, target, p))
|
||||
throw new ReferenceError("Access denied");
|
||||
throw new ReferenceError("封送对象的源运行域禁止了此项操作");
|
||||
|
||||
const args = [target, p];
|
||||
const dispatched = DomainMonitors.dispatch(
|
||||
|
@ -2387,7 +2388,7 @@ class Marshal {
|
|||
const rule = ruleRef.rule;
|
||||
|
||||
if (rule && !rule.canAccess(AccessAction.LIST, target))
|
||||
throw new ReferenceError("Access denied");
|
||||
throw new ReferenceError("封送对象的源运行域禁止了此项操作");
|
||||
|
||||
const args = [target];
|
||||
const dispatched = DomainMonitors.dispatch(
|
||||
|
@ -2414,7 +2415,7 @@ class Marshal {
|
|||
const rule = ruleRef.rule;
|
||||
|
||||
if (rule && !rule.canAccess(AccessAction.SEAL, target))
|
||||
throw new ReferenceError("Access denied");
|
||||
throw new ReferenceError("封送对象的源运行域禁止了此项操作");
|
||||
|
||||
const args = [target];
|
||||
const dispatched = DomainMonitors.dispatch(
|
||||
|
@ -2436,7 +2437,7 @@ class Marshal {
|
|||
|
||||
if (rule && !rule.canAccess(AccessAction.WRITE,
|
||||
target, p, marshalledNewValue, marshalledReceiver))
|
||||
throw new ReferenceError("Access denied");
|
||||
throw new ReferenceError("封送对象的源运行域禁止了此项操作");
|
||||
|
||||
const args = [target, p, marshalledNewValue, marshalledReceiver];
|
||||
const dispatched = DomainMonitors.dispatch(
|
||||
|
@ -2459,7 +2460,7 @@ class Marshal {
|
|||
const rule = ruleRef.rule;
|
||||
|
||||
if (rule && !rule.canAccess(AccessAction.META, target, marshalledV))
|
||||
throw new ReferenceError("Access denied");
|
||||
throw new ReferenceError("封送对象的源运行域禁止了此项操作");
|
||||
|
||||
const args = [target, marshalledV];
|
||||
const dispatched = DomainMonitors.dispatch(
|
||||
|
@ -3190,6 +3191,7 @@ class Sandbox {
|
|||
parseFloat: this.#domainWindow.parseFloat,
|
||||
isFinite: this.#domainWindow.isFinite,
|
||||
isNaN: this.#domainWindow.isNaN,
|
||||
Domain: Domain,
|
||||
};
|
||||
|
||||
const hardBuiltins = {
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
// 是否强制所有模式下使用沙盒
|
||||
const SANDBOX_FORCED = true;
|
||||
// 是否启用自动测试
|
||||
const SANDBOX_AUTOTEST = true;
|
||||
const SANDBOX_AUTOTEST = false;
|
||||
// 是否禁用自动测试延迟
|
||||
// 这将放弃渲染,在游戏结束前无响应
|
||||
const SANDBOX_AUTOTEST_NODELAY = false;
|
||||
|
||||
const WSURL_FOR_IP = /ws:\/\/(\d+.\d+.\d+.\d+):\d+\//;
|
||||
const TRUSTED_IPS = Object.freeze([
|
||||
"47.99.105.222",
|
||||
]);
|
||||
|
||||
// 声明导入类
|
||||
/** @type {boolean} */
|
||||
let SANDBOX_ENABLED = true;
|
||||
/** @type {typeof import("./sandbox.js").AccessAction} */
|
||||
|
@ -45,6 +47,7 @@ const sandboxStack = [];
|
|||
const isolatedsMap = new WeakMap();
|
||||
|
||||
// noname 顶级变量
|
||||
/** @type {Object<string|symbol, any>} */
|
||||
const topVariables = {
|
||||
lib: null,
|
||||
game: null,
|
||||
|
@ -54,8 +57,13 @@ const topVariables = {
|
|||
_status: null,
|
||||
gnc: null,
|
||||
};
|
||||
|
||||
// eval保存
|
||||
const defaultEval = window.eval;
|
||||
|
||||
// 对于 `lib.init.start` 的首次编译我们放宽
|
||||
let initStartParsed = false;
|
||||
// 是否软启用沙盒
|
||||
let sandBoxRequired = SANDBOX_FORCED;
|
||||
|
||||
// 可能的垫片函数
|
||||
|
@ -198,8 +206,19 @@ function requireSandbox() {
|
|||
* @param {string} ip
|
||||
*/
|
||||
function requireSandboxOn(ip) {
|
||||
if (!TRUSTED_IPS.includes(ip))
|
||||
if (!TRUSTED_IPS.includes(ip)) {
|
||||
sandBoxRequired = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (SANDBOX_FORCED
|
||||
&& topVariables.game
|
||||
&& topVariables.game.ws) {
|
||||
const match = WSURL_FOR_IP.exec(topVariables.game.ws.url);
|
||||
|
||||
if (match && match[1] === ip)
|
||||
sandBoxRequired = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -213,6 +232,28 @@ function isSandboxRequired() {
|
|||
return SANDBOX_ENABLED && sandBoxRequired;
|
||||
}
|
||||
|
||||
/**
|
||||
* ```plain
|
||||
* 是否可以跳过沙盒进行编译
|
||||
* ```
|
||||
*
|
||||
* @param {any} item
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function canSkipSandbox(item) {
|
||||
if (!topVariables.lib)
|
||||
return false;
|
||||
|
||||
if (item === topVariables.lib.init.start) {
|
||||
if (!initStartParsed) {
|
||||
initStartParsed = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* ```plain
|
||||
* 简单的、不带上下文的模拟eval函数
|
||||
|
@ -382,15 +423,8 @@ async function initSecurity({
|
|||
...Object.values(game.promises),
|
||||
defaultEval,
|
||||
window.require,
|
||||
window.process,
|
||||
window.module,
|
||||
window.exports,
|
||||
window.cordova,
|
||||
// @ts-ignore
|
||||
window.NonameAndroidBridge,
|
||||
// @ts-ignore
|
||||
window.noname_shijianInterfaces,
|
||||
window,
|
||||
window.define,
|
||||
];
|
||||
|
||||
// 构造禁止函数调用的规则
|
||||
|
@ -409,12 +443,25 @@ async function initSecurity({
|
|||
bannedRule.canMarshal = false; // 禁止获取
|
||||
bannedRule.setGranted(AccessAction.READ, false); // 禁止读取属性
|
||||
bannedRule.setGranted(AccessAction.WRITE, false); // 禁止读取属性
|
||||
bannedRule.setGranted(AccessAction.DEFINE, false); // 禁止定义属性
|
||||
bannedRule.setGranted(AccessAction.DESCRIBE, false); // 禁止描述属性
|
||||
bannedRule.setGranted(AccessAction.TRACE, false); // 禁止获取原型
|
||||
bannedRule.setGranted(AccessAction.META, false); // 禁止设置原型
|
||||
|
||||
// 禁止访问关键对象
|
||||
[
|
||||
lib.cheat,
|
||||
lib.node,
|
||||
lib.message,
|
||||
window.process,
|
||||
window.module,
|
||||
window.exports,
|
||||
window.cordova,
|
||||
// @ts-ignore
|
||||
window.NonameAndroidBridge,
|
||||
// @ts-ignore
|
||||
window.noname_shijianInterfaces,
|
||||
window,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.forEach(o => Marshal.setRule(o, bannedRule));
|
||||
|
@ -434,9 +481,10 @@ async function initSecurity({
|
|||
// 如果目标是 game 的 ioFuncs 包含的所有函数
|
||||
.require("target", game)
|
||||
.require("property", ...ioFuncs)
|
||||
.require("property", "ws")
|
||||
// 抛出异常
|
||||
.then(() => {
|
||||
throw "禁止修改关键函数";
|
||||
.then((access, nameds, control) => {
|
||||
throw `禁止沙盒修改 \`game.${nameds.prototype}\` 属性`;
|
||||
})
|
||||
// 让 Monitor 开始工作
|
||||
.start(); // 差点忘记启动了喵
|
||||
|
@ -517,6 +565,18 @@ function createSandbox() {
|
|||
// TODO: 仅提供必要的document函数(?)
|
||||
box.document = document;
|
||||
|
||||
if (topVariables.game
|
||||
&& topVariables.game.ws) {
|
||||
const match = WSURL_FOR_IP.exec(topVariables.game.ws.url);
|
||||
|
||||
if (match && TRUSTED_IPS.includes(match[1])) {
|
||||
box.scope.ArrayBuffer = ArrayBuffer;
|
||||
box.scope.localStorage = localStorage;
|
||||
box.scope.exports = undefined;
|
||||
box.scope.define = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// 传递七个变量
|
||||
Object.assign(box.scope, topVariables);
|
||||
// 复制垫片函数
|
||||
|
@ -563,6 +623,15 @@ function getIsolateds(sandbox) {
|
|||
* @returns {Array<typeof Function>}
|
||||
*/
|
||||
function getIsolatedsFrom(item) {
|
||||
if (canSkipSandbox(item) || !SANDBOX_ENABLED) {
|
||||
return [
|
||||
defaultFunction,
|
||||
defaultGeneratorFunction,
|
||||
defaultAsyncFunction,
|
||||
defaultAsyncGeneratorFunction,
|
||||
];
|
||||
}
|
||||
|
||||
const domain = Marshal.getMarshalledDomain(item) || Domain.caller;
|
||||
|
||||
// 非顶级域调用情况下我们替换掉Function类型
|
||||
|
@ -611,25 +680,26 @@ function importSandbox() {
|
|||
};
|
||||
}
|
||||
|
||||
// 原本的Function类型记录
|
||||
/** @type {typeof Function} */
|
||||
// @ts-ignore
|
||||
const defaultFunction = function () { }.constructor;
|
||||
/** @type {typeof Function} */
|
||||
// @ts-ignore
|
||||
const defaultGeneratorFunction = function* () { }.constructor;
|
||||
/** @type {typeof Function} */
|
||||
// @ts-ignore
|
||||
const defaultAsyncFunction = async function () { }.constructor;
|
||||
/** @type {typeof Function} */
|
||||
// @ts-ignore
|
||||
const defaultAsyncGeneratorFunction = async function* () { }.constructor;
|
||||
|
||||
/**
|
||||
* ```plain
|
||||
* 初始化顶级域的Funcion类型封装
|
||||
* ```
|
||||
*/
|
||||
function initIsolatedEnvironment() {
|
||||
/** @type {typeof Function} */
|
||||
// @ts-ignore
|
||||
const defaultFunction = function () { }.constructor;
|
||||
/** @type {typeof Function} */
|
||||
// @ts-ignore
|
||||
const defaultGeneratorFunction = function* () { }.constructor;
|
||||
/** @type {typeof Function} */
|
||||
// @ts-ignore
|
||||
const defaultAsyncFunction = async function () { }.constructor;
|
||||
/** @type {typeof Function} */
|
||||
// @ts-ignore
|
||||
const defaultAsyncGeneratorFunction = async function* () { }.constructor;
|
||||
|
||||
// @ts-ignore
|
||||
defaultSandbox = createSandbox(); // 所有 eval、parsex 代码全部丢进去喵
|
||||
|
||||
|
@ -827,11 +897,11 @@ function setupPolyfills(sandbox) {
|
|||
}
|
||||
|
||||
// 测试暴露喵
|
||||
// Reflect.defineProperty(window, "sandbox", {
|
||||
// get: () => defaultSandbox,
|
||||
// set: () => { },
|
||||
// configurable: true,
|
||||
// });
|
||||
Reflect.defineProperty(window, "sandbox", {
|
||||
get: () => defaultSandbox,
|
||||
set: () => { },
|
||||
configurable: true,
|
||||
});
|
||||
|
||||
const exports = {
|
||||
enterSandbox,
|
||||
|
|
Loading…
Reference in New Issue