Skip to content
quarry Artifact [7dd7c10c95]
Login

Artifact [7dd7c10c95]

Artifact 7dd7c10c950c5e39a22d8c0f9585696722626153404c6eec7464a947a9878acd:


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")
}