test(uploads): harden frontend map parser, drop dead getSafeFilename edit (codex review of #834)
- getFrontendExtensionMap now tolerates quoted keys and trailing comments and throws on any other unparsable map line, so future syntax drift fails loudly instead of silently dropping entries from the comparison. - Revert the .dng/.heic/.heif addition to getSafeFilename: the helper has no callers, so the edit was dead code. Live validation paths already cover these formats.
This commit is contained in:
@@ -21,9 +21,19 @@ function getFrontendExtensionMap() {
|
|||||||
const match = source.match(/const EXTENSION_TO_MIME[^=]*= \{([\s\S]*?)\n\};/);
|
const match = source.match(/const EXTENSION_TO_MIME[^=]*= \{([\s\S]*?)\n\};/);
|
||||||
if (!match) throw new Error('Could not find frontend EXTENSION_TO_MIME');
|
if (!match) throw new Error('Could not find frontend EXTENSION_TO_MIME');
|
||||||
|
|
||||||
return Object.fromEntries(
|
// Parse `key: 'mime',` entries — quoted keys and trailing `//` comments are
|
||||||
Array.from(match[1].matchAll(/^(\s*)(\w+): '([^']+)',?$/gm), ([, , extension, mime]) => [extension, mime])
|
// tolerated; any other non-blank, non-comment line inside the map is a parse
|
||||||
);
|
// failure, so a syntax the parser can't read fails loudly instead of silently
|
||||||
|
// dropping the entry from the comparison.
|
||||||
|
const entries = [];
|
||||||
|
for (const line of match[1].split('\n')) {
|
||||||
|
const trimmed = line.trim();
|
||||||
|
if (trimmed === '' || trimmed.startsWith('//')) continue;
|
||||||
|
const entry = trimmed.match(/^'?(\w+)'?\s*:\s*'([^']+)'\s*,?\s*(?:\/\/.*)?$/);
|
||||||
|
if (!entry) throw new Error(`Unparsable EXTENSION_TO_MIME line in frontend fileTypes.ts: "${trimmed}"`);
|
||||||
|
entries.push([entry[1], entry[2]]);
|
||||||
|
}
|
||||||
|
return Object.fromEntries(entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('configured upload file types', () => {
|
describe('configured upload file types', () => {
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ function getSafeFilename(originalFilename) {
|
|||||||
const ext = path.extname(originalFilename).toLowerCase();
|
const ext = path.extname(originalFilename).toLowerCase();
|
||||||
|
|
||||||
// Validate extension - including both image and video extensions
|
// Validate extension - including both image and video extensions
|
||||||
const validExtensions = ['.jpg', '.jpeg', '.png', '.webp', '.gif', '.dng', '.heic', '.heif', '.svg', '.ico', '.mp4', '.m4v', '.webm', '.mov', '.avi'];
|
const validExtensions = ['.jpg', '.jpeg', '.png', '.webp', '.gif', '.svg', '.ico', '.mp4', '.m4v', '.webm', '.mov', '.avi'];
|
||||||
if (!validExtensions.includes(ext)) {
|
if (!validExtensions.includes(ext)) {
|
||||||
throw new Error('Invalid file extension');
|
throw new Error('Invalid file extension');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user