mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 17:36:08 +08:00
64 lines
1.9 KiB
TypeScript
64 lines
1.9 KiB
TypeScript
import path from 'path';
|
|
import { parse } from 'shell-quote';
|
|
import { CompilableSource } from '@hydrooj/common';
|
|
import { fs } from '@hydrooj/utils';
|
|
import { FormatError } from './error';
|
|
|
|
const EMPTY_STR = /^[ \r\n\t]*$/i;
|
|
|
|
export const cmd = parse;
|
|
|
|
export namespace Lock {
|
|
const queue: Record<string, Array<(res?: any) => void>> = {};
|
|
|
|
export async function acquire(key: string) {
|
|
if (!queue[key]) {
|
|
queue[key] = [];
|
|
} else {
|
|
await new Promise((resolve) => {
|
|
queue[key].push(resolve);
|
|
});
|
|
}
|
|
}
|
|
|
|
export function release(key: string) {
|
|
if (!queue[key].length) delete queue[key];
|
|
else queue[key].shift()();
|
|
}
|
|
}
|
|
|
|
export function compilerText(stdout: string, stderr: string) {
|
|
const ret = [];
|
|
if (!EMPTY_STR.test(stdout)) ret.push(stdout.substring(0, 1024 * 1024));
|
|
if (!EMPTY_STR.test(stderr)) ret.push(stderr.substring(0, 1024 * 1024));
|
|
return ret.join('\n');
|
|
}
|
|
|
|
function restrictFile(p: string) {
|
|
if (!p) return '/';
|
|
if (p[0] === '/') p = '';
|
|
return p.replace(/\.\./gmi, '');
|
|
}
|
|
|
|
export function ensureFile(folder: string) {
|
|
return (src: CompilableSource, message: string) => {
|
|
const file = typeof src === 'string' ? src : src?.file;
|
|
if (file === '/dev/null') return file;
|
|
// Historical issue
|
|
if (file.includes('/')) {
|
|
const f = path.join(folder, restrictFile(file.split('/')[1]));
|
|
if (fs.existsSync(f)) {
|
|
const stat = fs.statSync(f);
|
|
if (stat.isFile()) return f;
|
|
}
|
|
}
|
|
const f = path.join(folder, restrictFile(file));
|
|
if (!fs.existsSync(f)) throw new FormatError(message, [file]);
|
|
const stat = fs.statSync(f);
|
|
if (!stat.isFile()) throw new FormatError(message, [file]);
|
|
return f;
|
|
};
|
|
}
|
|
|
|
export * from '@hydrooj/utils/lib/utils';
|