处理get/index.js;微调代码以符合语法检查
This commit is contained in:
parent
340cf27bd0
commit
3dbd145f79
|
@ -9,6 +9,7 @@ import { Promises } from "./promises.js";
|
||||||
import { rootURL } from "../../noname.js";
|
import { rootURL } from "../../noname.js";
|
||||||
import * as pinyinPro from "./pinyins/index.js";
|
import * as pinyinPro from "./pinyins/index.js";
|
||||||
import { Audio } from "./audio.js";
|
import { Audio } from "./audio.js";
|
||||||
|
import security from "../util/security.js";
|
||||||
|
|
||||||
export class Get {
|
export class Get {
|
||||||
is = new Is();
|
is = new Is();
|
||||||
|
@ -927,10 +928,10 @@ export class Get {
|
||||||
const target = constructor
|
const target = constructor
|
||||||
? Array.isArray(obj) || obj instanceof Map || obj instanceof Set || constructor === Object
|
? Array.isArray(obj) || obj instanceof Map || obj instanceof Set || constructor === Object
|
||||||
? // @ts-ignore
|
? // @ts-ignore
|
||||||
new constructor()
|
new constructor()
|
||||||
: constructor.name in window && /\[native code\]/.test(constructor.toString())
|
: constructor.name in window && /\[native code\]/.test(constructor.toString())
|
||||||
? // @ts-ignore
|
? // @ts-ignore
|
||||||
new constructor(obj)
|
new constructor(obj)
|
||||||
: obj
|
: obj
|
||||||
: Object.create(null);
|
: Object.create(null);
|
||||||
if (target === obj) return target;
|
if (target === obj) return target;
|
||||||
|
@ -1488,6 +1489,61 @@ export class Get {
|
||||||
infoPlayersOL(infos) {
|
infoPlayersOL(infos) {
|
||||||
return Array.from(infos || []).map(get.infoPlayerOL);
|
return Array.from(infos || []).map(get.infoPlayerOL);
|
||||||
}
|
}
|
||||||
|
/** 箭头函数头 */
|
||||||
|
static #arrowPattern = /^(?:async\b\s*)?(?:([\w$]+)|\((\s*[\w$]+(?:\s*=\s*.+?)?(?:\s*,\s*[\w$]+(?:\s*=\s*.+?)?)*\s*)?\))\s*=>/;
|
||||||
|
/** 标准函数头 */
|
||||||
|
static #fullPattern = /^([\w\s*]+)\((\s*[\w$]+(?:\s*=\s*.+?)?(?:\s*,\s*[\w$]+(?:\s*=\s*.+?)?)*\s*)?\)\s*\{/;
|
||||||
|
/**
|
||||||
|
* ```plain
|
||||||
|
* 测试一段代码是否为函数体
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param {string} code
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
static isFunctionBody(code) {
|
||||||
|
try {
|
||||||
|
new Function(code);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* ```plain
|
||||||
|
* 清洗函数体代码
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param {string} str
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static pureFunctionStr(str) {
|
||||||
|
str = str.trim();
|
||||||
|
const arrowMatch = Get.#arrowPattern.exec(str);
|
||||||
|
if (arrowMatch) {
|
||||||
|
const body = `return ${str.slice(arrowMatch[0].length)}`;
|
||||||
|
if (!Get.isFunctionBody(body)) {
|
||||||
|
console.error("发现疑似恶意的远程代码:", str);
|
||||||
|
return `()=>console.error("尝试执行疑似恶意的远程代码")`;
|
||||||
|
}
|
||||||
|
return `${arrowMatch[0]}{${body}}`;
|
||||||
|
}
|
||||||
|
if (!str.endsWith("}")) return '()=>console.warn("无法识别的远程代码")';
|
||||||
|
const fullMatch = Get.#fullPattern.exec(str);
|
||||||
|
if (!fullMatch) return '()=>console.warn("无法识别的远程代码")';
|
||||||
|
const head = fullMatch[1];
|
||||||
|
const args = fullMatch[2] || '';
|
||||||
|
const body = str.slice(fullMatch[0].length).slice(0, -1);
|
||||||
|
if (!Get.isFunctionBody(body)) {
|
||||||
|
console.error("发现疑似恶意的远程代码:", str);
|
||||||
|
return `()=>console.error("尝试执行疑似恶意的远程代码")`;
|
||||||
|
}
|
||||||
|
str = `(${args}){${body}}`;
|
||||||
|
if (head.includes("*")) str = "*" + str;
|
||||||
|
str = "function" + str;
|
||||||
|
if (/\basync\b/.test(head)) str = "async " + str;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
funcInfoOL(func) {
|
funcInfoOL(func) {
|
||||||
if (typeof func == "function") {
|
if (typeof func == "function") {
|
||||||
if (func._filter_args) {
|
if (func._filter_args) {
|
||||||
|
@ -1496,29 +1552,25 @@ export class Get {
|
||||||
const str = func.toString();
|
const str = func.toString();
|
||||||
// js内置的函数
|
// js内置的函数
|
||||||
if (/\{\s*\[native code\]\s*\}/.test(str)) return "_noname_func:function () {}";
|
if (/\{\s*\[native code\]\s*\}/.test(str)) return "_noname_func:function () {}";
|
||||||
return "_noname_func:" + str;
|
return "_noname_func:" + Get.pureFunctionStr(str);
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
infoFuncOL(info) {
|
infoFuncOL(info) {
|
||||||
let func;
|
let func;
|
||||||
const str = info.slice(13).trim();
|
const str = Get.pureFunctionStr(info.slice(13)); // 清洗函数并阻止注入
|
||||||
try {
|
try {
|
||||||
// js内置的函数
|
// js内置的函数
|
||||||
if (/\{\s*\[native code\]\s*\}/.test(str)) return function () {};
|
if (/\{\s*\[native code\]\s*\}/.test(str)) return function () { };
|
||||||
// 一般fun和数组形式
|
if (security.isSandboxRequired()) {
|
||||||
if (str.startsWith("function") || str.startsWith("(")) eval(`func=(${str});`);
|
const loadStr = `return (${str});`;
|
||||||
// 其他奇形怪状的fun
|
const box = security.currentSandbox();
|
||||||
else {
|
if (!box) throw new ReferenceError("没有找到当前沙盒");
|
||||||
try {
|
func = box.exec(loadStr);
|
||||||
eval(`func = ${str}`);
|
} else func = security.exec(`return (${str});`);
|
||||||
} catch {
|
|
||||||
eval(`let obj = {${str}}; func = obj[Object.keys(obj)[0]]`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`${e} in \n${str}`);
|
console.error(`${e} in \n${str}`);
|
||||||
return function () {};
|
return function () { };
|
||||||
}
|
}
|
||||||
if (Array.isArray(func)) {
|
if (Array.isArray(func)) {
|
||||||
func = get.filter.apply(this, get.parsedResult(func));
|
func = get.filter.apply(this, get.parsedResult(func));
|
||||||
|
@ -1528,14 +1580,14 @@ export class Get {
|
||||||
eventInfoOL(item, level, noMore) {
|
eventInfoOL(item, level, noMore) {
|
||||||
return get.itemtype(item) == "event"
|
return get.itemtype(item) == "event"
|
||||||
? `_noname_event:${JSON.stringify(
|
? `_noname_event:${JSON.stringify(
|
||||||
Object.entries(item).reduce((stringifying, entry) => {
|
Object.entries(item).reduce((stringifying, entry) => {
|
||||||
const key = entry[0];
|
const key = entry[0];
|
||||||
if (key == "_trigger") {
|
if (key == "_trigger") {
|
||||||
if (noMore !== false) stringifying[key] = get.eventInfoOL(entry[1], null, false);
|
if (noMore !== false) stringifying[key] = get.eventInfoOL(entry[1], null, false);
|
||||||
} else if (!lib.element.GameEvent.prototype[key] && key != "content" && get.itemtype(entry[1]) != "event") stringifying[key] = get.stringifiedResult(entry[1], null, false);
|
} else if (!lib.element.GameEvent.prototype[key] && key != "content" && get.itemtype(entry[1]) != "event") stringifying[key] = get.stringifiedResult(entry[1], null, false);
|
||||||
return stringifying;
|
return stringifying;
|
||||||
}, {})
|
}, {})
|
||||||
)}`
|
)}`
|
||||||
: "";
|
: "";
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -2074,8 +2126,8 @@ export class Get {
|
||||||
n = game.checkMod(from, to, n, "globalFrom", from);
|
n = game.checkMod(from, to, n, "globalFrom", from);
|
||||||
n = game.checkMod(from, to, n, "globalTo", to);
|
n = game.checkMod(from, to, n, "globalTo", to);
|
||||||
const equips1 = from.getCards("e", function (card) {
|
const equips1 = from.getCards("e", function (card) {
|
||||||
return !ui.selected.cards || !ui.selected.cards.includes(card);
|
return !ui.selected.cards || !ui.selected.cards.includes(card);
|
||||||
}),
|
}),
|
||||||
equips2 = to.getCards("e", function (card) {
|
equips2 = to.getCards("e", function (card) {
|
||||||
return !ui.selected.cards || !ui.selected.cards.includes(card);
|
return !ui.selected.cards || !ui.selected.cards.includes(card);
|
||||||
});
|
});
|
||||||
|
@ -4896,6 +4948,19 @@ export class Get {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function freezeSlot(obj, key) {
|
||||||
|
const descriptor = Reflect.getOwnPropertyDescriptor(obj, key);
|
||||||
|
if (!descriptor) return;
|
||||||
|
descriptor.writable = false;
|
||||||
|
descriptor.configurable = false;
|
||||||
|
Reflect.defineProperty(obj, key, descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
freezeSlot(Get, "isFunctionBody");
|
||||||
|
freezeSlot(Get, "pureFunctionStr");
|
||||||
|
freezeSlot(Get, "funcInfoOL");
|
||||||
|
freezeSlot(Get, "infoFuncOL");
|
||||||
|
|
||||||
export let get = new Get();
|
export let get = new Get();
|
||||||
/**
|
/**
|
||||||
* @param { InstanceType<typeof Get> } [instance]
|
* @param { InstanceType<typeof Get> } [instance]
|
||||||
|
|
|
@ -186,7 +186,7 @@ function _eval(x) {
|
||||||
* @param {Object} scope
|
* @param {Object} scope
|
||||||
* @returns {any}
|
* @returns {any}
|
||||||
*/
|
*/
|
||||||
function _exec(x, scope) {
|
function _exec(x, scope = {}) {
|
||||||
if (isPrimitive(scope))
|
if (isPrimitive(scope))
|
||||||
scope = {};
|
scope = {};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue