处理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 * as pinyinPro from "./pinyins/index.js";
import { Audio } from "./audio.js";
import security from "../util/security.js";
export class Get {
is = new Is();
@ -1488,6 +1489,61 @@ export class Get {
infoPlayersOL(infos) {
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) {
if (typeof func == "function") {
if (func._filter_args) {
@ -1496,29 +1552,25 @@ export class Get {
const str = func.toString();
// js内置的函数
if (/\{\s*\[native code\]\s*\}/.test(str)) return "_noname_func:function () {}";
return "_noname_func:" + str;
return "_noname_func:" + Get.pureFunctionStr(str);
}
return "";
}
infoFuncOL(info) {
let func;
const str = info.slice(13).trim();
const str = Get.pureFunctionStr(info.slice(13)); // 清洗函数并阻止注入
try {
// js内置的函数
if (/\{\s*\[native code\]\s*\}/.test(str)) return function () {};
// 一般fun和数组形式
if (str.startsWith("function") || str.startsWith("(")) eval(`func=(${str});`);
// 其他奇形怪状的fun
else {
try {
eval(`func = ${str}`);
} catch {
eval(`let obj = {${str}}; func = obj[Object.keys(obj)[0]]`);
}
}
if (/\{\s*\[native code\]\s*\}/.test(str)) return function () { };
if (security.isSandboxRequired()) {
const loadStr = `return (${str});`;
const box = security.currentSandbox();
if (!box) throw new ReferenceError("没有找到当前沙盒");
func = box.exec(loadStr);
} else func = security.exec(`return (${str});`);
} catch (e) {
console.error(`${e} in \n${str}`);
return function () {};
return function () { };
}
if (Array.isArray(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();
/**
* @param { InstanceType<typeof Get> } [instance]

View File

@ -186,7 +186,7 @@ function _eval(x) {
* @param {Object} scope
* @returns {any}
*/
function _exec(x, scope) {
function _exec(x, scope = {}) {
if (isPrimitive(scope))
scope = {};