完成扩展保存部分;处理library/index.js、library/init/index.js、connect.js

This commit is contained in:
IceCola 2024-05-25 13:44:27 +08:00
parent 6ffd290489
commit 2e6502c639
4 changed files with 81 additions and 28 deletions

View File

@ -2,6 +2,9 @@
game.import("mode", function (lib, game, ui, get, ai, _status) {
return {
name: "connect",
init() {
game.requireSandbox();
},
start: function () {
var directstartmode = lib.config.directstartmode;
ui.create.menu(true);

View File

@ -24,6 +24,7 @@ import * as Element from "./element/index.js";
import { updateURLs } from "./update-urls.js";
import { defaultHooks } from "./hooks/index.js";
import { freezeButExtensible } from "../util/index.js";
import security from "../util/security.js";
export class Library {
configprefix = "noname_0.9_";
@ -6333,8 +6334,8 @@ export class Library {
code = container.textarea.value;
}
try {
var character = null;
eval(code);
debugger; // NEED TO VIEW DATA
var { character } = security.exec2(code);
if (!Array.isArray(character)) {
throw "err";
}
@ -6421,8 +6422,8 @@ export class Library {
code = container.textarea.value;
}
try {
var character = null;
eval(code);
debugger; // NEED TO VIEW DATA
var { character } = security.exec2(code);
if (!Array.isArray(character)) {
throw "err";
}
@ -6850,8 +6851,8 @@ export class Library {
code = container.textarea.value;
}
try {
var character = null;
eval(code);
debugger; // NEED TO VIEW DATA
var { character } = security.exec2(code);
if (!get.is.object(character)) {
throw "err";
}
@ -7752,7 +7753,8 @@ 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);
obj = eval(code);
debugger; // NEED TO VIEW DATA
obj = security.eval(`return ${code};`);
if (![null, undefined].includes(obj)) {
const keys = Object.getOwnPropertyNames(obj)
.concat(Object.getOwnPropertyNames(Object.getPrototypeOf(obj)))
@ -9560,9 +9562,15 @@ export class Library {
if (!Array.isArray(message) || typeof lib.message.client[message[0]] !== "function") {
throw "err";
}
if (!game.sandbox) game.sandbox = security.createSandbox();
security.enterSandbox(game.sandbox);
try {
for (var i = 1; i < message.length; i++) {
message[i] = get.parsedResult(message[i]);
}
} finally {
security.exitSandbox();
}
} catch (e) {
console.log(e);
console.log("invalid message: " + messageevent.data);
@ -9597,6 +9605,7 @@ export class Library {
}
game.online = false;
game.ws = null;
game.sandbox = null;
},
},
/**
@ -12251,8 +12260,9 @@ export class Library {
log: function () {
var items = [];
try {
debugger; // NEED TO VIEW DATA
for (var i = 0; i < arguments.length; i++) {
eval("items.push(" + arguments[i] + ")");
items.push(security.eval(`return ${arguments[i]}`));
}
} catch (e) {
this.send("log", ["err"]);

View File

@ -11,6 +11,9 @@ import { GameEvent } from "../element/gameEvent.js";
import { GameEventPromise } from "../element/gameEventPromise.js";
import { rootURL } from "../../../noname.js";
import security from "../../util/security.js";
import { Domain, Marshal, Sandbox } from "../../util/sandbox.js";
export class LibInit {
/**
* 部分函数的Promise版本
@ -140,9 +143,17 @@ export class LibInit {
if (!Array.isArray(message) || typeof lib.message.server[message[0]] !== "function") {
throw "err";
}
if (!client.sandbox) client.sandbox = security.createSandbox();
// @ts-ignore
security.enterSandbox(client.sandbox);
try {
for (var i = 1; i < message.length; i++) {
message[i] = get.parsedResult(message[i]);
}
} finally {
// @ts-ignore
security.exitSandbox(client.sandbox);
}
} catch (e) {
console.log(e);
console.log("invalid message: " + messagestr);
@ -283,7 +294,8 @@ export class LibInit {
if (data.includes("sojson") || data.includes("jsjiami") || data.includes("var _0x")) alert(`检测到您安装了使用免费版sojson进行加密的扩展。请谨慎使用这些扩展避免游戏数据遭到破坏。\n扩展文件:${pathToRead}`);
}
try {
window.eval(data);
debugger; // NEED TO VIEW DATA
security.eval(data);
if (typeof onLoad == "function") onLoad();
} catch (error) {
if (typeof onError == "function") onError(error);
@ -584,6 +596,33 @@ export class LibInit {
* @returns
*/
parsex(item, scope) {
let ModFunction = Function;
let ModGeneratorFunction = GeneratorFunction;
// let ModAsyncFunction = AsyncFunction;
// let ModAsyncGeneratorFunction = AsyncGeneratorFunction;
// 虽然现在 parsex 被控制到了沙盒,
// 但是因为默认沙盒还是可以额外操作东西,
// 故而对不同的运行域做了区分
if (security.SANDBOX_ENABLED) {
const domain = Marshal.getMarshalledDomain(item) || Domain.caller;
// 非顶级域调用情况下我们替换掉Function类型
if (domain && domain !== Domain.topDomain) {
const sandbox = Sandbox.from(domain);
if (!sandbox)
throw "意外的运行域: 运行域没有绑定沙盒";
[
ModFunction,
ModGeneratorFunction,
// ModAsyncFunction,
// ModAsyncGeneratorFunction,
] = security.getIsolateds(sandbox);
}
}
//by 诗笺、Tipx-L
/**
* @param {Function} func
@ -608,7 +647,7 @@ export class LibInit {
debuggerCopy = debuggerCopy.slice(0, debuggerSkip + debuggerResult.index) + insertDebugger + debuggerCopy.slice(debuggerSkip + debuggerResult.index + debuggerResult[0].length, -1);
//测试是否有错误
try {
new GeneratorFunction(debuggerCopy);
new ModGeneratorFunction(debuggerCopy);
str = debuggerCopy + "}";
debuggerSkip += debuggerResult.index + insertDebugger.length;
hasDebugger = true;
@ -635,7 +674,7 @@ export class LibInit {
copy = copy.slice(0, skip + result.index) + insertStr + copy.slice(skip + result.index + result[0].length);
//测试是否有错误
try {
new (hasDebugger ? GeneratorFunction : Function)(copy);
new (hasDebugger ? ModGeneratorFunction : ModFunction)(copy);
str = copy;
skip += result.index + insertStr.length;
} catch (error) {
@ -647,11 +686,12 @@ export class LibInit {
str = `if(event.step==${k}){event.finish();return;}` + str;
}
if (!scope) {
return new (hasDebugger ? GeneratorFunction : Function)("event", "step", "source", "player", "target", "targets", "card", "cards", "skill", "forced", "num", "trigger", "result", "_status", "lib", "game", "ui", "get", "ai", str);
return new (hasDebugger ? ModGeneratorFunction : ModFunction)("event", "step", "source", "player", "target", "targets", "card", "cards", "skill", "forced", "num", "trigger", "result", "_status", "lib", "game", "ui", "get", "ai", str);
} else {
return scope(`function${hasDebugger ? "*" : ""} anonymous(event,step,source,player,target,targets,
new (hasDebugger ? ModGeneratorFunction : ModFunction)(str); // 防止注入喵
return scope(`(function${hasDebugger ? "*" : ""}(event,step,source,player,target,targets,
card,cards,skill,forced,num,trigger,result,
_status,lib,game,ui,get,ai){${str}}; anonymous;`);
_status,lib,game,ui,get,ai){${str}})`);
}
}
switch (typeof item) {
@ -687,7 +727,8 @@ export class LibInit {
};
} else {
if (Symbol.iterator in item) return lib.init.parsex(Array.from(item));
if (item.toString !== Object.prototype.toString) return lib.init.parsex(item.toString());
// 根据狂神喵的建议禁用parsex接受字符串喵
// if (item.toString !== Object.prototype.toString) return lib.init.parsex(item.toString());
if ("render" in item) {
// TODO: Object Render Parse
throw new Error("NYI: Object Render Parse");
@ -744,22 +785,24 @@ export class LibInit {
content._gen = true;
return content;
} else if (item._parsed) return item;
// falls through
default:
return Legacy(item);
default:
throw new TypeError("为确保安全禁止用parsex解析字符串");
}
}
eval(func) {
if (typeof func == "function") {
return eval("(" + func.toString() + ")");
debugger; // NEED TO VIEW DATA
return security.eval(`return (${func.toString()});`);
} else if (typeof func == "object") {
for (var i in func) {
if (Object.prototype.hasOwnProperty.call(func, i)) {
if (typeof func[i] == "function") {
let checkObject = {};
checkObject[i] = func[i];
return eval(`(function(){return ${get.stringify(checkObject)};})()`)[i];
debugger; // NEED TO VIEW DATA
return security.eval(`return ${get.stringify(checkObject)};`)[i];
} else {
func[i] = lib.init.eval(func[i]);
}

View File

@ -333,20 +333,17 @@ export const extensionMenu = function (connectMenu) {
inputExtName.disabled = true;
setTimeout(function () {
var ext = {};
var config = null,
help = null;
debugger; // NEED TO VIEW DATA
for (var i in dash4.content) {
try {
if (i == "content" || i == "precontent") {
({ config, help, return: ext[i] } = security.exec2(`return (${dash4.content[i]});`));
ext[i] = security.exec2(`return (${dash4.content[i]});`).return;
if (typeof ext[i] != "function") {
throw "err";
} else {
ext[i] = ext[i].toString();
}
} else {
({ config, help, return: ext[i] } = security.exec2(`${dash4.content[i]}; return (${i});`));
ext[i] = security.exec2(dash4.content[i])[i];
if (ext[i] == null || typeof ext[i] != "object") {
throw "err";
} else {