package sniff
import "testing"
func TestImageSignatures(t *testing.T) {
for _, c := range []struct {
raw []byte
want string
}{
{append([]byte("\x89PNG\r\n\x1a\n"), []byte("IHDR")...), "image/png"},
{append([]byte{0xff, 0xd8, 0xff, 0xe0}, []byte("0000JFIF")...), "image/jpeg"},
{[]byte("GIF87a............"), "image/gif"},
{[]byte("GIF89a............"), "image/gif"},
{append([]byte("RIFF....WEBPVP8 "), []byte("rest")...), "image/webp"},
} {
got, ok := Image(c.raw)
if !ok || got != c.want {
t.Errorf("FAIL: Image answered %q %v, want %q", got, ok, c.want)
}
}
t.Log("ok: the four raster signatures each answer their own type")
}
func TestImageRefusesEverythingElse(t *testing.T) {
for _, raw := range [][]byte{
[]byte(`<svg xmlns="http://www.w3.org/2000/svg"></svg>`),
[]byte("%PDF-1.7"),
append([]byte("RIFF....WAVEfmt "), []byte("rest")...),
{0x89},
nil,
} {
if got, ok := Image(raw); ok {
t.Errorf("FAIL: Image admitted %q for %q", got, raw)
}
}
t.Log("ok: SVG, PDF, WAV and short reads are not inline images")
}
func TestMediaSignatures(t *testing.T) {
for _, c := range []struct {
raw []byte
want string
}{
{append([]byte{0, 0, 0, 0x18}, []byte("ftypisom....")...), "video/mp4"},
{append([]byte{0x1a, 0x45, 0xdf, 0xa3}, []byte("webm........")...), "video/webm"},
{[]byte("OggS............"), "audio/ogg"},
{append([]byte("ID3"), []byte("\x04\x00\x00\x00\x00\x00\x00")...), "audio/mpeg"},
{[]byte{0xff, 0xfb, 0x90, 0x44, 0, 0, 0, 0}, "audio/mpeg"},
{append([]byte("RIFF....WAVEfmt "), []byte("rest")...), "audio/wav"},
} {
got, ok := Media(c.raw)
if !ok || got != c.want {
t.Errorf("FAIL: Media answered %q %v, want %q", got, ok, c.want)
}
}
t.Log("ok: MP4, WebM, Ogg, MP3 and WAV each answer their own type")
}
func TestMediaRefusesImagesAndText(t *testing.T) {
for _, raw := range [][]byte{
append([]byte("RIFF....WEBPVP8 "), []byte("rest")...),
append([]byte("\x89PNG\r\n\x1a\n"), []byte("IHDR")...),
[]byte("hello, world\n"),
nil,
} {
if got, ok := Media(raw); ok {
t.Errorf("FAIL: Media admitted %q for %q", got, raw)
}
}
t.Log("ok: WebP, PNG and prose are not media")
}
func TestKindClassifies(t *testing.T) {
for _, c := range []struct {
raw []byte
want string
}{
{append([]byte("\x89PNG\r\n\x1a\n"), []byte("IHDR")...), KindImage},
{append([]byte("RIFF....WAVEfmt "), []byte("rest")...), KindMedia},
{[]byte("package main\n\nfunc main() {}\n"), KindText},
{[]byte("%PDF-1.7\n\x00\x01binary"), KindOther},
{[]byte("\x00\x00\x00"), KindOther},
{nil, KindOther},
} {
if got := Kind(c.raw); got != c.want {
t.Errorf("FAIL: Kind answered %q, want %q", got, c.want)
}
}
t.Log("ok: image, media, text and other are decided from the bytes")
}
// A file that begins with text and turns binary is not text: the NUL
// scan reads the whole slice, because a preview that stops at the first
// screen would hand a reader escape sequences from a binary tail.
func TestTextRefusesEmbeddedNUL(t *testing.T) {
if Text([]byte("readable for a while\n\x00\x01\x02")) {
t.Fatal("FAIL: a NUL past the first line still counts as text")
}
if !Text([]byte("plain\nlines\n")) {
t.Fatal("FAIL: plain lines are not text")
}
t.Log("ok: text means valid UTF-8 with no NUL anywhere")
}
// A bounded read cuts where the bound falls. A document that is plainly
// text must not be called binary because its prefix ends mid-character.
func TestTrimPartialRuneKeepsPrefixesReadable(t *testing.T) {
whole := []byte("héllo wörld — a dash")
for n := 1; n <= len(whole); n++ {
prefix := TrimPartialRune(whole[:n])
if n >= 2 && !Text(prefix) {
t.Fatalf("FAIL: a %d-byte prefix of plain text read as binary: %q", n, prefix)
}
}
// A tail that is not a partial rune at all is left where it is, so
// real garbage is still garbage.
bad := []byte("ok\xff\xfe\xfd\xfc")
if got := TrimPartialRune(bad); len(got) != len(bad) {
t.Fatalf("FAIL: an invalid tail was trimmed away: %q", got)
}
if Text(TrimPartialRune(bad)) {
t.Fatal("FAIL: invalid bytes passed as text after trimming")
}
t.Log("ok: a rune cut by the bound is dropped; invalid bytes are not")
}