mirror of
https://github.com/keanuplayz/TravBot-v3.git
synced 2024-08-15 02:33:12 +00:00
Added a timeout to regex search
This commit is contained in:
parent
b3e1b5e140
commit
3b1b8ec914
1 changed files with 48 additions and 6 deletions
|
@ -2,6 +2,9 @@ import {GuildEmoji} from "discord.js";
|
||||||
import {MessageEmbed} from "discord.js";
|
import {MessageEmbed} from "discord.js";
|
||||||
import Command from "../../core/command";
|
import Command from "../../core/command";
|
||||||
import {CommonLibrary} from "../../core/lib";
|
import {CommonLibrary} from "../../core/lib";
|
||||||
|
import vm from "vm";
|
||||||
|
|
||||||
|
const REGEX_TIMEOUT_MS = 1000;
|
||||||
|
|
||||||
export default new Command({
|
export default new Command({
|
||||||
description: "Lists all emotes the bot has in it's registry,",
|
description: "Lists all emotes the bot has in it's registry,",
|
||||||
|
@ -19,13 +22,52 @@ export default new Command({
|
||||||
|
|
||||||
displayEmoteList($, $.client.emojis.cache.filter((emote) => emote.guild.id === guildID).array());
|
displayEmoteList($, $.client.emojis.cache.filter((emote) => emote.guild.id === guildID).array());
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, by comparing inputs
|
// Otherwise, search via a regex pattern
|
||||||
const query = $.args.join(" ").toLowerCase();
|
let flags: string | undefined = undefined;
|
||||||
|
|
||||||
displayEmoteList(
|
if (/^-[dgimsuy]{1,7}$/.test($.args[$.args.length - 1])) {
|
||||||
$,
|
flags = $.args.pop().substring(1);
|
||||||
$.client.emojis.cache.filter((emote) => emote.name.toLowerCase().includes(query)).array()
|
}
|
||||||
);
|
|
||||||
|
let emoteCollection = $.client.emojis.cache.array();
|
||||||
|
// Creates a sandbox to stop a regular expression if it takes too much time to search.
|
||||||
|
// To avoid passing in a giant data structure, I'll just pass in the structure {[id: string]: [name: string]}.
|
||||||
|
//let emotes: {[id: string]: string} = {};
|
||||||
|
let emotes = new Map<string, string>();
|
||||||
|
|
||||||
|
for (const emote of emoteCollection) {
|
||||||
|
emotes.set(emote.id, emote.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The result will be sandbox.emotes because it'll be modified in-place.
|
||||||
|
const sandbox = {
|
||||||
|
regex: new RegExp($.args.join(" "), flags),
|
||||||
|
emotes
|
||||||
|
};
|
||||||
|
const context = vm.createContext(sandbox);
|
||||||
|
|
||||||
|
if (vm.isContext(sandbox)) {
|
||||||
|
// Restrict an entire query to the timeout specified.
|
||||||
|
try {
|
||||||
|
const script = new vm.Script(
|
||||||
|
"for(const [id, name] of emotes.entries()) if(!regex.test(name)) emotes.delete(id);"
|
||||||
|
);
|
||||||
|
script.runInContext(context, {timeout: REGEX_TIMEOUT_MS});
|
||||||
|
emotes = sandbox.emotes;
|
||||||
|
emoteCollection = emoteCollection.filter((emote) => emote.id in emotes); // Only allow emotes that haven't been deleted.
|
||||||
|
displayEmoteList($, emoteCollection);
|
||||||
|
} catch (error) {
|
||||||
|
if (error.code === "ERR_SCRIPT_EXECUTION_TIMEOUT") {
|
||||||
|
$.channel.send(
|
||||||
|
`The regular expression you entered exceeded the time limit of ${REGEX_TIMEOUT_MS} milliseconds.`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$.channel.send("Failed to initialize sandbox.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue