7e6ce91001
评审加固五项: - manifest 形态守卫:bundle 在场而 metadata.manifest 非数组 → throw(与 storageRoot 守卫同风格),不与"bundle 合法缺席=空清单"共用静默空 coercion - 侧车门控:空清单下级②不可达,跳过侧车加载——破损侧车副本不因无用输入 让整 job 失败 - public_path 冲突 catch 按约束名精确认领(postgres.js 的 constraint_name, drizzle 包一层在 cause)——未来加第三唯一索引不误标,其余 23505 原样上抛 - 集成用例:不同 source_url 同旧 uploads 路径 → 后到不覆盖、issue 报告、 只留一行(mediaRegistered=1) - 单测边界对拍:'<svg' 恰好收在 1024 字节窗口内(起点 1020)检出;起点 1021 被截断为 '<sv' → null 310 测试(308+2);typecheck/lint 三绿。 Co-Authored-By: Claude Code <noreply@anthropic.com>
76 lines
3.6 KiB
TypeScript
76 lines
3.6 KiB
TypeScript
// magic-bytes 单测(Plan 3 Task 4 Step 1):六类签名各正例 + 伪签名 null 例 +
|
||
// SVG 大小写不敏感 + 窗口边界(1KB 外不检出)+ 二进制签名优先于文本特征。
|
||
// 期望值全部手写字面量(与实现零共享——对拍而非引用)。
|
||
import { describe, expect, it } from 'vitest'
|
||
import { detectMediaType } from '../../apps/api/src/modules/import/magic-bytes.js'
|
||
|
||
const PNG_SIG = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])
|
||
|
||
describe('detectMediaType 手写签名表', () => {
|
||
it('六类二进制签名正例:PNG/JPEG/GIF87a/GIF89a/WEBP/PDF', () => {
|
||
expect(detectMediaType(Buffer.concat([PNG_SIG, Buffer.from('rest-of-png')]))).toStrictEqual({
|
||
type: 'image/png',
|
||
svg: false,
|
||
})
|
||
expect(detectMediaType(Buffer.from([0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10]))).toStrictEqual({
|
||
type: 'image/jpeg',
|
||
svg: false,
|
||
})
|
||
expect(detectMediaType(Buffer.from('GIF87a-more-gif'))).toStrictEqual({ type: 'image/gif', svg: false })
|
||
expect(detectMediaType(Buffer.from('GIF89a-more-gif'))).toStrictEqual({ type: 'image/gif', svg: false })
|
||
expect(
|
||
detectMediaType(Buffer.concat([Buffer.from('RIFF'), Buffer.from([0x24, 0x00, 0x00, 0x00]), Buffer.from('WEBPVP8 ')])),
|
||
).toStrictEqual({ type: 'image/webp', svg: false })
|
||
expect(detectMediaType(Buffer.from('%PDF-1.7\n%fake-payload'))).toStrictEqual({
|
||
type: 'application/pdf',
|
||
svg: false,
|
||
})
|
||
})
|
||
|
||
it('SVG 文本特征:大小写不敏感(<svg / <SVG / <Svg,含 xml 声明前导),svg=true', () => {
|
||
expect(detectMediaType(Buffer.from('<svg xmlns="http://www.w3.org/2000/svg"/>'))).toStrictEqual({
|
||
type: 'image/svg+xml',
|
||
svg: true,
|
||
})
|
||
expect(detectMediaType(Buffer.from('<?xml version="1.0"?><SVG onload="x()">'))).toStrictEqual({
|
||
type: 'image/svg+xml',
|
||
svg: true,
|
||
})
|
||
expect(detectMediaType(Buffer.from('<!-- c --><Svg width="1">'))).toStrictEqual({
|
||
type: 'image/svg+xml',
|
||
svg: true,
|
||
})
|
||
})
|
||
|
||
it('伪签名 / 纯文本 / 空缓冲 → null(未知签名不猜格式)', () => {
|
||
expect(detectMediaType(Buffer.from('hello plain text note'))).toBe(null)
|
||
expect(detectMediaType(Buffer.from([0x00, 0x01, 0x02, 0x03]))).toBe(null)
|
||
expect(detectMediaType(Buffer.alloc(0))).toBe(null)
|
||
})
|
||
|
||
it('RIFF 非 WEBP(WAV)不误报 webp → null', () => {
|
||
expect(
|
||
detectMediaType(Buffer.concat([Buffer.from('RIFF'), Buffer.from([0x24, 0x00, 0x00, 0x00]), Buffer.from('WAVEfmt ')])),
|
||
).toBe(null)
|
||
})
|
||
|
||
it('二进制签名优先:PNG 头 + 尾部 <svg 片段仍判 PNG(文本窗口只对非二进制生效)', () => {
|
||
const sneaky = Buffer.concat([PNG_SIG, Buffer.from('<svg onload="alert(1)"> trailing')])
|
||
expect(detectMediaType(sneaky)).toStrictEqual({ type: 'image/png', svg: false })
|
||
})
|
||
|
||
it('SVG 窗口 1KB 钉死:<svg 出现在 1KB 之后不检出 → null', () => {
|
||
const beyond = Buffer.concat([Buffer.alloc(1200, 0x20), Buffer.from('<svg>')])
|
||
expect(detectMediaType(beyond)).toBe(null)
|
||
})
|
||
|
||
it('SVG 窗口边界逐字节对拍:<svg 恰好收在 1024 字节内 → 检出;起点 1021 被截断 → null', () => {
|
||
// '<svg' 起点索引 1020:占 1020-1023,末字节恰在窗口(0-1023)内 → 检出
|
||
const flush = Buffer.concat([Buffer.alloc(1020, 0x20), Buffer.from('<svg')])
|
||
expect(detectMediaType(flush)).toStrictEqual({ type: 'image/svg+xml', svg: true })
|
||
// 起点索引 1021:窗口只含 '<sv','g' 被截在窗外 → 不检出
|
||
const truncated = Buffer.concat([Buffer.alloc(1021, 0x20), Buffer.from('<svg')])
|
||
expect(detectMediaType(truncated)).toBe(null)
|
||
})
|
||
})
|