处理get/index.js;微调代码以符合语法检查

This commit is contained in:
IceCola 2024-05-25 11:58:23 +08:00
parent 340cf27bd0
commit 3dbd145f79
2 changed files with 92 additions and 27 deletions

View File

@ -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();
@ -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));
@ -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]

View File

@ -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 = {};