ASCIInator/server/__tests__/extSanitize.spec.js
dev c1cf06ed67 feat: initial commit — ASCIInator v0.1
Vue 3 + Vite + Tailwind frontend, Fastify API server, execa shell bridge.
All components built, server validated, 41 unit tests passing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 19:47:57 +00:00

36 lines
1.2 KiB
JavaScript

import { describe, it, expect } from 'vitest'
import path from 'node:path'
const SAFE_EXTS = new Set(['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.tiff', '.tif', '.avif'])
function sanitizeExt(filename) {
const rawExt = path.extname(filename || '').toLowerCase()
return SAFE_EXTS.has(rawExt) ? rawExt : '.jpg'
}
describe('extension sanitization', () => {
it('allows known image extensions', () => {
expect(sanitizeExt('photo.png')).toBe('.png')
expect(sanitizeExt('photo.jpg')).toBe('.jpg')
expect(sanitizeExt('photo.WEBP')).toBe('.webp')
})
it('falls back to .jpg for dangerous extensions', () => {
expect(sanitizeExt('exploit.svg')).toBe('.jpg')
expect(sanitizeExt('exploit.mvg')).toBe('.jpg')
expect(sanitizeExt('exploit.msl')).toBe('.jpg')
expect(sanitizeExt('exploit.sh')).toBe('.jpg')
expect(sanitizeExt('exploit.eps')).toBe('.jpg')
})
it('falls back to .jpg for missing or empty filename', () => {
expect(sanitizeExt('')).toBe('.jpg')
expect(sanitizeExt(null)).toBe('.jpg')
})
it('ignores path components — only extension is used', () => {
expect(sanitizeExt('../../etc/passwd.png')).toBe('.png')
expect(sanitizeExt('../../etc/passwd')).toBe('.jpg')
})
})