Files
Crussell/backend/internal/images/validate_test.go
T
popertotsandSisyphus 510828c924
CI / Go vulnerabilities (push) Successful in 1m10s
CI / Build & Vet (push) Successful in 1m39s
CI / Frontend build (gate) (push) Successful in 1m42s
CI / Frontend QC (audit) (push) Successful in 56s
CI / Frontend QC (typecheck) (push) Successful in 1m36s
CI / Frontend QC (lint) (push) Successful in 1m51s
CI / Tests (prod) (push) Has been cancelled
CI / Tests (dev) (push) Has been cancelled
CI / Race (prod) (push) Has been cancelled
CI / Race (dev) (push) Has been cancelled
chore: run go fix for Go 1.26 modernization
106 files: interface{}→any, strings.Split→SplitSeq, CutPrefix/Cut, strings.Builder, slices.Contains, remove redundant // +build directives, gofmt import ordering and indentation.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-09 17:25:23 +01:00

266 lines
8.7 KiB
Go

//go:build test
package images
import (
"bytes"
"testing"
)
// TestValidateImageBytes_JPEG verifies that JPEG magic bytes (FF D8 FF) are detected.
func TestValidateImageBytes_JPEG(t *testing.T) {
data := []byte{0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01}
ext, err := ValidateImageBytes(data)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if ext != ".jpg" {
t.Errorf("expected .jpg, got %q", ext)
}
}
// TestValidateImageBytes_PNG verifies that PNG magic bytes are detected.
func TestValidateImageBytes_PNG(t *testing.T) {
data := []byte{0x89, 'P', 'N', 'G', '\r', '\n', 0x1a, '\n', 0x00, 0x00, 0x00, 0x0d}
ext, err := ValidateImageBytes(data)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if ext != ".png" {
t.Errorf("expected .png, got %q", ext)
}
}
// TestValidateImageBytes_GIF87a verifies GIF87a magic bytes are detected.
func TestValidateImageBytes_GIF87a(t *testing.T) {
data := []byte{'G', 'I', 'F', '8', '7', 'a', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
ext, err := ValidateImageBytes(data)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if ext != ".gif" {
t.Errorf("expected .gif, got %q", ext)
}
}
// TestValidateImageBytes_GIF89a verifies GIF89a magic bytes are detected.
func TestValidateImageBytes_GIF89a(t *testing.T) {
data := []byte{'G', 'I', 'F', '8', '9', 'a', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
ext, err := ValidateImageBytes(data)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if ext != ".gif" {
t.Errorf("expected .gif, got %q", ext)
}
}
// TestValidateImageBytes_WebP verifies RIFF...WEBP magic bytes are detected.
func TestValidateImageBytes_WebP(t *testing.T) {
data := []byte{'R', 'I', 'F', 'F', 0x00, 0x00, 0x00, 0x00, 'W', 'E', 'B', 'P'}
ext, err := ValidateImageBytes(data)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if ext != ".webp" {
t.Errorf("expected .webp, got %q", ext)
}
}
// TestValidateImageBytes_AVIF verifies ftypavif magic bytes are detected.
func TestValidateImageBytes_AVIF(t *testing.T) {
data := []byte{0x00, 0x00, 0x00, 0x20, 'f', 't', 'y', 'p', 'a', 'v', 'i', 'f'}
ext, err := ValidateImageBytes(data)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if ext != ".avif" {
t.Errorf("expected .avif, got %q", ext)
}
}
// TestValidateImageBytes_AVIS verifies ftypavis (AVIF image sequence) magic bytes are detected.
func TestValidateImageBytes_AVIS(t *testing.T) {
data := []byte{0x00, 0x00, 0x00, 0x20, 'f', 't', 'y', 'p', 'a', 'v', 'i', 's'}
ext, err := ValidateImageBytes(data)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if ext != ".avif" {
t.Errorf("expected .avif, got %q", ext)
}
}
// TestValidateImageBytes_JXL verifies ftypjxl magic bytes are detected.
func TestValidateImageBytes_JXL(t *testing.T) {
data := []byte{0x00, 0x00, 0x00, 0x0c, 'f', 't', 'y', 'p', 'j', 'x', 'l', ' '}
ext, err := ValidateImageBytes(data)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if ext != ".jxl" {
t.Errorf("expected .jxl, got %q", ext)
}
}
// TestValidateImageBytes_TooSmall verifies that files smaller than 12 bytes are rejected.
func TestValidateImageBytes_TooSmall(t *testing.T) {
data := []byte{0xff, 0xd8, 0xff}
_, err := ValidateImageBytes(data)
if err == nil {
t.Fatal("expected error for too-small file, got nil")
}
}
// TestValidateImageBytes_UnknownFormat verifies that unrecognized magic bytes return an error.
func TestValidateImageBytes_UnknownFormat(t *testing.T) {
data := []byte("this is not an image file at all!!")
_, err := ValidateImageBytes(data)
if err == nil {
t.Fatal("expected error for unknown format, got nil")
}
}
// TestValidateImageBytes_Exact12Bytes verifies the boundary condition of exactly 12 bytes.
func TestValidateImageBytes_Exact12Bytes(t *testing.T) {
// Valid JPEG header truncated to exactly 12 bytes (should still match 3-byte magic)
data := []byte{0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01}
ext, err := ValidateImageBytes(data)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if ext != ".jpg" {
t.Errorf("expected .jpg, got %q", ext)
}
}
// TestValidateImageBytes_WebPNotRIFF verifies that WEBP without RIFF prefix is rejected.
func TestValidateImageBytes_WebPNotRIFF(t *testing.T) {
data := []byte{'W', 'E', 'B', 'P', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
_, err := ValidateImageBytes(data)
if err == nil {
t.Fatal("expected error for WEBP without RIFF prefix, got nil")
}
}
// TestValidateImageBytes_AVIFWrongBrand verifies that ftyp with wrong brand is rejected.
func TestValidateImageBytes_AVIFWrongBrand(t *testing.T) {
// ftyp with "mp41" brand (not avif/avis)
data := []byte{0x00, 0x00, 0x00, 0x20, 'f', 't', 'y', 'p', 'm', 'p', '4', '1'}
_, err := ValidateImageBytes(data)
if err == nil {
t.Fatal("expected error for non-AVIF ftyp, got nil")
}
}
// TestValidateImageBytes_Empty verifies that empty input is rejected.
func TestValidateImageBytes_Empty(t *testing.T) {
data := []byte{}
_, err := ValidateImageBytes(data)
if err == nil {
t.Fatal("expected error for empty input, got nil")
}
}
// TestValidateImageBytes_AllSupportedFormats verifies every supported format returns a non-empty extension.
func TestValidateImageBytes_AllSupportedFormats(t *testing.T) {
tests := []struct {
name string
data []byte
wantExt string
wantErr bool
}{
{"JPEG", []byte{0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01}, ".jpg", false},
{"PNG", []byte{0x89, 'P', 'N', 'G', '\r', '\n', 0x1a, '\n', 0, 0, 0, 0}, ".png", false},
{"GIF87a", []byte{'G', 'I', 'F', '8', '7', 'a', 0, 0, 0, 0, 0, 0}, ".gif", false},
{"GIF89a", []byte{'G', 'I', 'F', '8', '9', 'a', 0, 0, 0, 0, 0, 0}, ".gif", false},
{"WebP", []byte{'R', 'I', 'F', 'F', 0, 0, 0, 0, 'W', 'E', 'B', 'P'}, ".webp", false},
{"AVIF", []byte{0, 0, 0, 0x20, 'f', 't', 'y', 'p', 'a', 'v', 'i', 'f'}, ".avif", false},
{"AVIS", []byte{0, 0, 0, 0x20, 'f', 't', 'y', 'p', 'a', 'v', 'i', 's'}, ".avif", false},
{"JXL", []byte{0, 0, 0, 0x0c, 'f', 't', 'y', 'p', 'j', 'x', 'l', ' '}, ".jxl", false},
{"Random", []byte("not-an-image-file!"), "", true},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
ext, err := ValidateImageBytes(tc.data)
if tc.wantErr {
if err == nil {
t.Errorf("expected error, got nil")
}
} else {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if ext != tc.wantExt {
t.Errorf("expected %q, got %q", tc.wantExt, ext)
}
}
})
}
}
// TestValidateImageBytes_NoFalsePositiveJPEG verifies that data starting with FF D8 but not FF D8 FF is rejected.
func TestValidateImageBytes_NoFalsePositiveJPEG(t *testing.T) {
data := []byte{0xff, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
_, err := ValidateImageBytes(data)
if err == nil {
t.Fatal("expected error for non-JPEG starting with FF D8, got nil")
}
}
// TestValidateImageBytes_PartialMagic verifies that partial magic bytes (e.g., only first 2 bytes of PNG) are rejected.
func TestValidateImageBytes_PartialMagic(t *testing.T) {
// Only first 2 bytes of PNG signature
data := []byte{0x89, 'P', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
_, err := ValidateImageBytes(data)
if err == nil {
t.Fatal("expected error for partial PNG magic, got nil")
}
}
// BenchmarkValidateImageBytes measures validation throughput.
func BenchmarkValidateImageBytes(b *testing.B) {
data := []byte{0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = ValidateImageBytes(data)
}
}
// BenchmarkValidateImageBytes_AVIF measures AVIF detection throughput.
func BenchmarkValidateImageBytes_AVIF(b *testing.B) {
data := []byte{0x00, 0x00, 0x00, 0x20, 'f', 't', 'y', 'p', 'a', 'v', 'i', 'f'}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = ValidateImageBytes(data)
}
}
// BenchmarkValidateImageBytes_WebP measures WebP detection throughput.
func BenchmarkValidateImageBytes_WebP(b *testing.B) {
data := []byte{'R', 'I', 'F', 'F', 0x00, 0x00, 0x00, 0x00, 'W', 'E', 'B', 'P'}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = ValidateImageBytes(data)
}
}
// BenchmarkValidateImageBytes_JXL measures JXL detection throughput.
func BenchmarkValidateImageBytes_JXL(b *testing.B) {
data := []byte{0x00, 0x00, 0x00, 0x0c, 'f', 't', 'y', 'p', 'j', 'x', 'l', ' '}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = ValidateImageBytes(data)
}
}
// TestValidateImageBytes_11Bytes verifies that 11-byte files (just under the 12-byte minimum) are rejected.
func TestValidateImageBytes_11Bytes(t *testing.T) {
data := bytes.Repeat([]byte{0x00}, 11)
_, err := ValidateImageBytes(data)
if err == nil {
t.Fatal("expected error for 11-byte file, got nil")
}
}