forked from h2non/filetype
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 4af2d19
Showing
18 changed files
with
767 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
root = true | ||
|
||
[*] | ||
indent_style = tabs | ||
indent_size = 2 | ||
end_of_line = lf | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true | ||
|
||
[*.md] | ||
trim_trailing_whitespace = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/bimg | ||
/bundle | ||
bin | ||
/*.jpg | ||
/*.png | ||
/*.webp | ||
/fixtures/*_out.* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
language: go | ||
go: | ||
- 1.5 | ||
- 1.4 | ||
- 1.3 | ||
- release | ||
- tip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
The MIT License | ||
|
||
Copyright (c) Tomas Aparicio | ||
|
||
Permission is hereby granted, free of charge, to any person | ||
obtaining a copy of this software and associated documentation | ||
files (the "Software"), to deal in the Software without | ||
restriction, including without limitation the rights to use, | ||
copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the | ||
Software is furnished to do so, subject to the following | ||
conditions: | ||
|
||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# filetype [![Build Status](https://travis-ci.org/h2non/filetype.png)](https://travis-ci.org/h2non/filetype) [![GoDoc](https://godoc.org/github.com/h2non/filetype?status.svg)](https://godoc.org/github.com/h2non/filetype) | ||
|
||
Small [Go](https://golang.org) package to infer the file type checking the [magic number](https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files) of a given binary buffer. | ||
|
||
Supports a wide range of file types, including images formats, fonts, videos, audio and other common application files, and provides the proper file extension and convenient MIME code. | ||
|
||
## Installation | ||
|
||
```bash | ||
go get gopkg.in/h2non/filetype.v0 | ||
``` | ||
|
||
## Usage | ||
|
||
```go | ||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"gopkg.in/h2non/filetype.v0" | ||
) | ||
|
||
func main() { | ||
buf, _ := ioutil.ReadFile("sample.jpg") | ||
|
||
kind, unkwown := filetype.Type(buf) | ||
if unkwown != nil { | ||
fmt.Printf("Unkwown file type") | ||
return | ||
} | ||
|
||
fmt.Printf("File type found: %s. MIME: %s", kind.Extension, kind.MIME.Value) | ||
} | ||
``` | ||
|
||
## API | ||
|
||
|
||
|
||
## License | ||
|
||
MIT - Tomas Aparicio |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package filetype | ||
|
||
import ( | ||
"errors" | ||
"gopkg.in/h2non/filetype.v0/matchers" | ||
"gopkg.in/h2non/filetype.v0/types" | ||
) | ||
|
||
// Map of extensions and file types | ||
var Types = types.Types | ||
|
||
// Map of file matchers | ||
var Matchers = matchers.Matchers | ||
|
||
// Default types | ||
var Empty = types.Empty | ||
var Unknown = types.Unknown | ||
|
||
// Predefined errors | ||
var EmptyBufferErr = errors.New("Empty buffer") | ||
var UnknownBufferErr = errors.New("Unknown buffer type") | ||
|
||
func DoMatch(buf []byte) (types.Type, error) { | ||
return matchers.Match(buf) | ||
} | ||
|
||
// Infer the file type of a buffer inspecting the magic numbers | ||
func Match(buf []byte) (types.Type, error) { | ||
return DoMatch(buf) | ||
} | ||
|
||
// Alias to Match() | ||
func Type(buf []byte) (types.Type, error) { | ||
return Match(buf) | ||
} | ||
|
||
func doMatchMap(buf []byte, machers matchers.Map) (types.Type, error) { | ||
kind := matchers.MatchMap(buf, machers) | ||
if kind != types.Unknown { | ||
return kind, nil | ||
} | ||
return kind, UnknownBufferErr | ||
} | ||
|
||
// Match file as image type | ||
func Image(buf []byte) (types.Type, error) { | ||
return doMatchMap(buf, matchers.Image) | ||
} | ||
|
||
// Match file as audio type | ||
func Audio(buf []byte) (types.Type, error) { | ||
return doMatchMap(buf, matchers.Audio) | ||
} | ||
|
||
// Match file as video type | ||
func Video(buf []byte) (types.Type, error) { | ||
return doMatchMap(buf, matchers.Audio) | ||
} | ||
|
||
// Match file as text font type | ||
func Font(buf []byte) (types.Type, error) { | ||
return doMatchMap(buf, matchers.Font) | ||
} | ||
|
||
// Match file as generic archive type | ||
func Archive(buf []byte) (types.Type, error) { | ||
return doMatchMap(buf, matchers.Archive) | ||
} | ||
|
||
func Is(buf []byte, ext string) bool { | ||
kind, ok := types.Types[ext] | ||
if ok { | ||
return IsType(buf, kind) | ||
} | ||
return false | ||
} | ||
|
||
func IsType(buf []byte, kind types.Type) bool { | ||
matcher := matchers.Matchers[kind] | ||
if matcher == nil { | ||
return false | ||
} | ||
|
||
length := len(buf) | ||
return matcher(buf, length) != types.Unknown | ||
} | ||
|
||
// Register a new matcher type | ||
func AddMatcher(fileType types.Type, matcher matchers.Matcher) matchers.TypeMatcher { | ||
return matchers.NewMatcher(fileType, matcher) | ||
} | ||
|
||
// Register a new file type | ||
func AddType(ext, mime string) types.Type { | ||
return types.NewType(ext, mime) | ||
} | ||
|
||
// Check if a given file extension is supported | ||
func IsSupported(ext string) bool { | ||
for name, _ := range Types { | ||
if name == ext { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
// Check if a given MIME expression is supported | ||
func IsMIMESupported(mime string) bool { | ||
for _, m := range Types { | ||
if m.MIME.Value == mime { | ||
return true | ||
} | ||
} | ||
return false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package filetype | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func TestMatches(t *testing.T) { | ||
cases := []struct { | ||
buf []byte | ||
ext string | ||
}{ | ||
{[]byte{0xFF, 0xD8, 0xFF}, "jpg"}, | ||
} | ||
|
||
for _, test := range cases { | ||
match, err := Match(test.buf) | ||
if err != nil { | ||
t.Fatalf("Error: %s", err) | ||
} | ||
|
||
if match.Extension != test.ext { | ||
t.Fatalf("Invalid image type: %s", match.Extension) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
package matchers | ||
|
||
var TypeEpub = NewType("epub", "application/epub+zip") | ||
var TypeZip = NewType("zip", "application/zip") | ||
var TypeTar = NewType("tar", "application/x-tar") | ||
var TypeRar = NewType("rar", "application/x-rar-compressed") | ||
var TypeGz = NewType("gz", "application/gzip") | ||
var TypeBz2 = NewType("bz2", "application/x-bzip2") | ||
var Type7z = NewType("7z", "application/x-7z-compressed") | ||
var TypeXz = NewType("xz", "application/x-xz") | ||
var TypePdf = NewType("pdf", "application/pdf") | ||
var TypeExe = NewType("exe", "application/x-msdownload") | ||
var TypeSwf = NewType("swf", "application/x-shockwave-flash") | ||
var TypeRtf = NewType("rtf", "application/rtf") | ||
var TypeEot = NewType("eot", "application/octet-stream") | ||
var TypePs = NewType("ps", "application/postscript") | ||
var TypeSqlite = NewType("sqlite", "application/x-sqlite3") | ||
|
||
var Archive = Map{ | ||
TypeEpub: Epub, | ||
TypeZip: Zip, | ||
TypeTar: Tar, | ||
TypeRar: Rar, | ||
TypeBz2: Bz2, | ||
Type7z: SevenZ, | ||
TypeXz: Xz, | ||
TypePdf: Pdf, | ||
TypeExe: Exe, | ||
TypeSwf: Swf, | ||
TypeRtf: Rtf, | ||
TypeEot: Eot, | ||
TypePs: Ps, | ||
TypeSqlite: Sqlite, | ||
} | ||
|
||
func Epub(buf []byte, length int) bool { | ||
return length > 57 && | ||
buf[0] == 0x50 && buf[1] == 0x4B && buf[2] == 0x3 && buf[3] == 0x4 && | ||
buf[30] == 0x6D && buf[31] == 0x69 && buf[32] == 0x6D && buf[33] == 0x65 && | ||
buf[34] == 0x74 && buf[35] == 0x79 && buf[36] == 0x70 && buf[37] == 0x65 && | ||
buf[38] == 0x61 && buf[39] == 0x70 && buf[40] == 0x70 && buf[41] == 0x6C && | ||
buf[42] == 0x69 && buf[43] == 0x63 && buf[44] == 0x61 && buf[45] == 0x74 && | ||
buf[46] == 0x69 && buf[47] == 0x6F && buf[48] == 0x6E && buf[49] == 0x2F && | ||
buf[50] == 0x65 && buf[51] == 0x70 && buf[52] == 0x75 && buf[53] == 0x62 && | ||
buf[54] == 0x2B && buf[55] == 0x7A && buf[56] == 0x69 && buf[57] == 0x70 | ||
} | ||
|
||
func Zip(buf []byte, length int) bool { | ||
return length > 3 && | ||
buf[0] == 0x50 && buf[1] == 0x4B && | ||
(buf[2] == 0x3 || buf[2] == 0x5 || buf[2] == 0x7) && | ||
(buf[3] == 0x4 || buf[3] == 0x6 || buf[3] == 0x8) | ||
} | ||
|
||
func Tar(buf []byte, length int) bool { | ||
return length > 261 && | ||
buf[257] == 0x75 && buf[258] == 0x73 && | ||
buf[259] == 0x74 && buf[260] == 0x61 && | ||
buf[261] == 0x72 | ||
} | ||
|
||
func Rar(buf []byte, length int) bool { | ||
return length > 6 && | ||
buf[0] == 0x52 && buf[1] == 0x61 && buf[2] == 0x72 && | ||
buf[3] == 0x21 && buf[4] == 0x1A && buf[5] == 0x7 && | ||
(buf[6] == 0x0 || buf[6] == 0x1) | ||
} | ||
|
||
func Gz(buf []byte, length int) bool { | ||
return length > 2 && | ||
buf[0] == 0x1F && buf[1] == 0x8B && buf[2] == 0x8 | ||
} | ||
|
||
func Bz2(buf []byte, length int) bool { | ||
return length > 2 && | ||
buf[0] == 0x42 && buf[1] == 0x5A && buf[2] == 0x68 | ||
} | ||
|
||
func SevenZ(buf []byte, length int) bool { | ||
return length > 5 && | ||
buf[0] == 0x37 && buf[1] == 0x7A && buf[2] == 0xBC && | ||
buf[3] == 0xAF && buf[4] == 0x27 && buf[5] == 0x1C | ||
} | ||
|
||
func Pdf(buf []byte, length int) bool { | ||
return length > 3 && | ||
buf[0] == 0x25 && buf[1] == 0x50 && | ||
buf[2] == 0x44 && buf[3] == 0x46 | ||
} | ||
|
||
func Exe(buf []byte, length int) bool { | ||
return length > 1 && | ||
buf[0] == 0x4D && buf[1] == 0x5A | ||
} | ||
|
||
func Swf(buf []byte, length int) bool { | ||
return length > 2 && | ||
(buf[0] == 0x43 || buf[0] == 0x46) && | ||
buf[1] == 0x57 && buf[2] == 0x53 | ||
} | ||
|
||
func Rtf(buf []byte, length int) bool { | ||
return length > 4 && | ||
buf[0] == 0x7B && buf[1] == 0x5C && | ||
buf[2] == 0x72 && buf[3] == 0x74 && | ||
buf[4] == 0x66 | ||
} | ||
|
||
func Eot(buf []byte, length int) bool { | ||
return length > 10 && | ||
buf[34] == 0x4C && buf[35] == 0x50 && | ||
((buf[8] == 0x02 && buf[9] == 0x00 && | ||
buf[10] == 0x01) || (buf[8] == 0x01 && | ||
buf[9] == 0x00 && buf[10] == 0x00) || | ||
(buf[8] == 0x02 && buf[9] == 0x00 && buf[10] == 0x02)) | ||
} | ||
|
||
func Ps(buf []byte, length int) bool { | ||
return length > 1 && | ||
buf[0] == 0x25 && buf[1] == 0x21 | ||
} | ||
|
||
func Xz(buf []byte, length int) bool { | ||
return length > 5 && | ||
buf[0] == 0xFD && buf[1] == 0x37 && | ||
buf[2] == 0x7A && buf[3] == 0x58 && | ||
buf[4] == 0x5A && buf[5] == 0x00 | ||
} | ||
|
||
func Sqlite(buf []byte, length int) bool { | ||
return length > 3 && | ||
buf[0] == 0x53 && buf[1] == 0x51 && | ||
buf[2] == 0x4C && buf[3] == 0x69 | ||
} |
Oops, something went wrong.