28 lines
1.2 KiB
TypeScript
28 lines
1.2 KiB
TypeScript
import path from "path";
|
|
|
|
const EXECUTABLE_EXTENSIONS = new Set([
|
|
".bat", ".cmd", ".com", ".dll", ".exe", ".hta", ".htm", ".html",
|
|
".jar", ".js", ".jsp", ".mjs", ".cjs", ".msi", ".php", ".phtml",
|
|
".phar", ".ps1", ".sh", ".vbs", ".war", ".wsf",
|
|
]);
|
|
|
|
export function isExecutableAttachment(filename: string): boolean {
|
|
return EXECUTABLE_EXTENSIONS.has(path.extname(filename).toLowerCase());
|
|
}
|
|
|
|
export async function hasValidImageSignature(file: Blob): Promise<boolean> {
|
|
const bytes = new Uint8Array(await file.slice(0, 16).arrayBuffer());
|
|
if (bytes.length < 3) return false;
|
|
|
|
const jpeg = bytes[0] === 0xff && bytes[1] === 0xd8 && bytes[2] === 0xff;
|
|
const png = bytes.length >= 8 &&
|
|
bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4e && bytes[3] === 0x47 &&
|
|
bytes[4] === 0x0d && bytes[5] === 0x0a && bytes[6] === 0x1a && bytes[7] === 0x0a;
|
|
const gifHeader = bytes.length >= 6 ? String.fromCharCode(...bytes.slice(0, 6)) : "";
|
|
const gif = gifHeader === "GIF87a" || gifHeader === "GIF89a";
|
|
const webp = bytes.length >= 12 &&
|
|
String.fromCharCode(...bytes.slice(0, 4)) === "RIFF" &&
|
|
String.fromCharCode(...bytes.slice(8, 12)) === "WEBP";
|
|
|
|
return jpeg || png || gif || webp;
|
|
}
|