From 9feb32a329d5a4aed228d952a58333577cd99e0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20Gul=C3=A1csi?= Date: Thu, 23 Jan 2014 21:55:37 +0100 Subject: [PATCH] Add some common file signatures to magic. Change-Id: I428933fdb5bb987113ae1bbd1161eca4c477b426 --- pkg/magic/magic.go | 27 +++++++++++++++++++++++++++ pkg/magic/magic_test.go | 9 +++++++++ pkg/magic/testdata/foo.tar.xz | Bin 0 -> 208 bytes pkg/magic/testdata/foo.tbz2 | Bin 0 -> 165 bytes pkg/magic/testdata/magic.pdf | Bin 0 -> 21668 bytes 5 files changed, 36 insertions(+) create mode 100644 pkg/magic/testdata/foo.tar.xz create mode 100644 pkg/magic/testdata/foo.tbz2 create mode 100644 pkg/magic/testdata/magic.pdf diff --git a/pkg/magic/magic.go b/pkg/magic/magic.go index 0edf01654..2a0744ed8 100644 --- a/pkg/magic/magic.go +++ b/pkg/magic/magic.go @@ -30,6 +30,8 @@ type prefixEntry struct { mtype string } +// usable source: http://www.garykessler.net/library/file_sigs.html +// mime types: http://www.iana.org/assignments/media-types/media-types.xhtml var prefixTable = []prefixEntry{ {[]byte("GIF87a"), "image/gif"}, {[]byte("GIF89a"), "image/gif"}, // TODO: Others? @@ -39,8 +41,33 @@ var prefixTable = []prefixEntry{ {[]byte("\xff\xd8\xff\xdb"), "image/jpeg"}, {[]byte("\x49\x49\x2a\x00\x10\x00\x00\x00\x43\x52\x02"), "image/cr2"}, {[]byte{137, 'P', 'N', 'G', '\r', '\n', 26, 10}, "image/png"}, + {[]byte{0x49, 0x20, 0x49}, "image/tiff"}, + {[]byte{0x49, 0x49, 0x2A, 0}, "image/tiff"}, + {[]byte{0x4D, 0x4D, 0, 0x2A}, "image/tiff"}, + {[]byte{0x4D, 0x4D, 0, 0x2B}, "image/tiff"}, + {[]byte("8BPS"), "image/vnd.adobe.photoshop"}, + {[]byte("gimp xcf "), "image/xcf"}, {[]byte("-----BEGIN PGP PUBLIC KEY BLOCK---"), "text/x-openpgp-public-key"}, + {[]byte("fLaC\x00\x00\x00"), "audio/flac"}, {[]byte{'I', 'D', '3'}, "audio/mpeg"}, + {[]byte{0, 0, 1, 0xB7}, "video/mpeg"}, + {[]byte{0, 0, 0, 0x14, 0x66, 0x74, 0x79, 0x70, 0x71, 0x74, 0x20, 0x20}, "video/quicktime"}, + {[]byte{0, 0x6E, 0x1E, 0xF0}, "application/vnd.ms-powerpoint"}, + {[]byte{0x1A, 0x45, 0xDF, 0xA3}, "video/webm"}, + {[]byte("FLV\x01"), "application/vnd.adobe.flash.video"}, + {[]byte{0x1F, 0x8B, 0x08}, "application/gzip"}, + {[]byte{0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C}, "application/x-7z-compressed"}, + {[]byte("BZh"), "application/bzip2"}, + {[]byte{0xFD, 0x37, 0x7A, 0x58, 0x5A, 0}, "application/x-xz"}, + {[]byte{'P', 'K', 3, 4, 0x0A, 0, 2, 0}, "application/epub+zip"}, + {[]byte{0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}, "application/vnd.ms-word"}, + {[]byte{'P', 'K', 3, 4, 0x0A, 0x14, 0, 6, 0}, "application/vnd.openxmlformats-officedocument.custom-properties+xml"}, + {[]byte{'P', 'K', 3, 4}, "application/zip"}, + {[]byte("%PDF"), "application/pdf"}, + {[]byte("{rtf"), "text/rtf1"}, + {[]byte("BEGIN:VCARD\x0D\x0A"), "text/vcard"}, + {[]byte("Return-Path: "), "message/rfc822"}, + // TODO(bradfitz): popular audio & video formats at least } diff --git a/pkg/magic/magic_test.go b/pkg/magic/magic_test.go index e81a7f3d3..140ced336 100644 --- a/pkg/magic/magic_test.go +++ b/pkg/magic/magic_test.go @@ -31,6 +31,15 @@ type magicTest struct { var tests = []magicTest{ {fileName: "smile.jpg", want: "image/jpeg"}, {fileName: "smile.png", want: "image/png"}, + {fileName: "smile.psd", want: "image/vnd.adobe.photoshop"}, + {fileName: "smile.tiff", want: "image/tiff"}, + {fileName: "smile.xcf", want: "image/xcf"}, + {fileName: "smile.gif", want: "image/gif"}, + {fileName: "foo.tar.gz", want: "application/gzip"}, + {fileName: "foo.tar.xz", want: "application/x-xz"}, + {fileName: "foo.tbz2", want: "application/bzip2"}, + {fileName: "foo.zip", want: "application/zip"}, + {fileName: "magic.pdf", want: "application/pdf"}, {data: "foo", want: "text/html"}, {data: "\xff", want: ""}, } diff --git a/pkg/magic/testdata/foo.tar.xz b/pkg/magic/testdata/foo.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..bfcceda15ef0dde916e186a3230dfff82c9c9ee9 GIT binary patch literal 208 zcmV;>05AXjH+ooF000E$*0e?f03iVu0001VFXf})C;tGCT>vv1>|OxfG-0AA4ZN_c z-IZM!&Q&e9df}W#tgiFND4G>6i5VA9i>gcsgEZn&`q3B$V`#yyV~EV z8-gkUaTX8IE06_*zMU298@wY+LdM~TC-GVx^hPkaCQ?7o#vChn=a-XRE$+}qn9Cj^ z*2ON#9HF@bwBvpy4%Yh_Hk5eFNqZ8EJwzpqh2S^L1gprO?G8vW;VZx*Yfr>JS!y1vqemF2R z0Po^ri30LUgohk~6NG{h5eS&8s2KWS(X1Xqb$X6!pjK*lW%8SupA8>#V`DLig$oue TSgFuRKa05{oG3_3MgbfEcWpj4 literal 0 HcmV?d00001 diff --git a/pkg/magic/testdata/magic.pdf b/pkg/magic/testdata/magic.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0e9340c04b35adb19ff57bface3e97f77ae14810 GIT binary patch literal 21668 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 literal 0 HcmV?d00001