Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 47740x 47740x 11x 308x 46345x 46345x 46345x 46345x 11x 308x 11x 11x 47740x 47740x 11x 11x 308x 308x 308x 308x 308x 308x 308x 47740x 47740x 308x 308x 11x | import { glob } from "lib/helpers/glob";
import { eventsRoot } from "consts";
import {
FileReaderFn,
ScriptEventHandlerWithCleanup,
} from "lib/scriptEventsHandlers/handlerTypes";
import { readFile, readFileSync } from "fs-extra";
import { loadScriptEventHandlerFromUntrustedString } from "lib/scriptEventsHandlers/untrustedHandler";
import { loadScriptEventHandlerFromTrustedString } from "lib/scriptEventsHandlers/trustedHandler";
import { dirname, join } from "path";
import { isAssetWithinProject } from "lib/helpers/assets";
import l10n from "shared/lib/lang/l10n";
const eventHandlers: Record<string, ScriptEventHandlerWithCleanup> = {};
const fileCache = new Map<string, string | Buffer>();
const loadUntrustedScriptEventHandler = async (
path: string,
fileReader: FileReaderFn,
): Promise<ScriptEventHandlerWithCleanup> => {
const handlerCode = await readFile(path, "utf8");
return loadScriptEventHandlerFromUntrustedString(
handlerCode,
path,
fileReader,
);
};
const loadTrustedScriptEventHandler = async (
path: string,
fileReader: FileReaderFn,
): Promise<ScriptEventHandlerWithCleanup> => {
const handlerCode = await readFile(path, "utf8");
return loadScriptEventHandlerFromTrustedString(handlerCode, path, fileReader);
};
const cleanupScriptEventHandlers = () => {
for (const key in eventHandlers) {
const handler = eventHandlers[key];
Eif (handler) {
handler.cleanup();
delete eventHandlers[key];
}
}
};
const cleanupFileCache = () => {
fileCache.clear();
};
const cacheKey = (absPath: string, enc?: BufferEncoding) =>
`${absPath}::${enc ?? "<binary>"}`;
const createFileReaderForHandler = (pluginPath: string): FileReaderFn => {
const dirPath = dirname(pluginPath);
function readPluginFile(filePath: string, encoding: "utf8"): string;
function readPluginFile(
filePath: string,
encoding?: BufferEncoding,
): string | Buffer;
function readPluginFile(filePath: string, encoding?: BufferEncoding) {
const absPath = join(dirPath, filePath);
guardFileWithinPlugin(absPath, dirPath);
const key = cacheKey(absPath, encoding);
const cached = fileCache.get(key);
if (cached !== undefined) {
return cached;
}
const value = readFileSync(absPath, encoding);
fileCache.set(key, value);
return value;
}
return readPluginFile;
};
export const guardFileWithinPlugin = (
assetPath: string,
projectRoot: string,
) => {
if (!isAssetWithinProject(assetPath, projectRoot)) {
throw new Error(
l10n("ERROR_FILE_DOESNT_BELONG_TO_CURRENT_PLUGIN", { file: assetPath }),
);
}
};
const loadAllScriptEventHandlers = async (projectRoot: string) => {
cleanupScriptEventHandlers();
cleanupFileCache();
const forceUntrusted = process.env.FORCE_QUICKJS_PLUGINS === "true";
const corePaths = await glob("event*.js", {
cwd: eventsRoot,
absolute: true,
});
const pluginPaths = await glob("plugins/*/**/events/event*.js", {
cwd: projectRoot,
absolute: true,
});
const trustedHandler = forceUntrusted
? loadUntrustedScriptEventHandler
: loadTrustedScriptEventHandler;
for (const path of corePaths) {
const handler = await trustedHandler(
path,
createFileReaderForHandler(path),
);
eventHandlers[handler.id] = handler;
}
for (const path of pluginPaths) {
const handler = await loadUntrustedScriptEventHandler(
path,
createFileReaderForHandler(path),
);
eventHandlers[handler.id] = handler;
}
return eventHandlers;
};
export default loadAllScriptEventHandlers;
|