3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-05-10 12:25:02 +00:00

Run user-supplied regexes in worker threads with a timeout

This commit is contained in:
Dragory 2020-08-05 01:15:36 +03:00
parent 19b97bc32b
commit a7fa258f2a
No known key found for this signature in database
GPG key ID: 5F387BA66DF8AAC1
15 changed files with 237 additions and 43 deletions

View file

@ -6,6 +6,8 @@ import { GuildSavedMessages } from "src/data/GuildSavedMessages";
import { onMessageCreate } from "./util/onMessageCreate";
import { onMessageUpdate } from "./util/onMessageUpdate";
import { trimPluginDescription } from "../../utils";
import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners";
import { LogsPlugin } from "../Logs/LogsPlugin";
const defaultOptions: PluginOptions<CensorPluginType> = {
config: {
@ -51,6 +53,7 @@ export const CensorPlugin = zeppelinPlugin<CensorPluginType>()("censor", {
`),
},
dependencies: [LogsPlugin],
configSchema: ConfigSchema,
defaultOptions,
@ -60,6 +63,8 @@ export const CensorPlugin = zeppelinPlugin<CensorPluginType>()("censor", {
state.serverLogs = new GuildLogs(guild.id);
state.savedMessages = GuildSavedMessages.getGuildInstance(guild.id);
state.regexRunner = getRegExpRunner(`guild-${pluginData.guild.id}`);
state.onMessageCreateFn = msg => onMessageCreate(pluginData, msg);
state.savedMessages.events.on("create", state.onMessageCreateFn);
@ -68,6 +73,8 @@ export const CensorPlugin = zeppelinPlugin<CensorPluginType>()("censor", {
},
onUnload(pluginData) {
discardRegExpRunner(`guild-${pluginData.guild.id}`);
pluginData.state.savedMessages.events.off("create", pluginData.state.onMessageCreateFn);
pluginData.state.savedMessages.events.off("update", pluginData.state.onMessageUpdateFn);
},

View file

@ -1,9 +1,10 @@
import * as t from "io-ts";
import { BasePluginType, eventListener } from "knub";
import { tNullable } from "src/utils";
import { TSafeRegex } from "src/validatorUtils";
import { TRegex } from "src/validatorUtils";
import { GuildLogs } from "src/data/GuildLogs";
import { GuildSavedMessages } from "src/data/GuildSavedMessages";
import { RegExpRunner } from "../../RegExpRunner";
export const ConfigSchema = t.type({
filter_zalgo: t.boolean,
@ -18,7 +19,7 @@ export const ConfigSchema = t.type({
domain_blacklist: tNullable(t.array(t.string)),
blocked_tokens: tNullable(t.array(t.string)),
blocked_words: tNullable(t.array(t.string)),
blocked_regex: tNullable(t.array(TSafeRegex)),
blocked_regex: tNullable(t.array(TRegex)),
});
export type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
@ -28,6 +29,8 @@ export interface CensorPluginType extends BasePluginType {
serverLogs: GuildLogs;
savedMessages: GuildSavedMessages;
regexRunner: RegExpRunner;
onMessageCreateFn;
onMessageUpdateFn;
};

View file

@ -8,6 +8,7 @@ import cloneDeep from "lodash.clonedeep";
import { censorMessage } from "./censorMessage";
import escapeStringRegexp from "escape-string-regexp";
import { logger } from "src/logger";
import { allowTimeout } from "../../../RegExpRunner";
export async function applyFiltersToMsg(
pluginData: PluginData<CensorPluginType>,
@ -137,17 +138,13 @@ export async function applyFiltersToMsg(
}
// Filter regex
const blockedRegex: RegExp[] = config.blocked_regex || [];
for (const [i, regex] of blockedRegex.entries()) {
if (typeof regex.test !== "function") {
logger.info(
`[DEBUG] Regex <${regex}> was not a regex; index ${i} of censor.blocked_regex for guild ${pluginData.guild.name} (${pluginData.guild.id})`,
);
continue;
}
for (const regex of config.blocked_regex || []) {
// We're testing both the original content and content + attachments/embeds here so regexes that use ^ and $ still match the regular content properly
if (regex.test(savedMessage.data.content) || regex.test(messageContent)) {
const matches =
(await pluginData.state.regexRunner.exec(regex, savedMessage.data.content).catch(allowTimeout)) ||
(await pluginData.state.regexRunner.exec(regex, messageContent).catch(allowTimeout));
if (matches) {
censorMessage(pluginData, savedMessage, `blocked regex (\`${regex.source}\`) found`);
return true;
}