...
1 package magic
2
3 import (
4 "bytes"
5 "encoding/binary"
6 "strings"
7 )
8
9 var (
10
11 Odt = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.text"), 30)
12
13 Ott = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.text-template"), 30)
14
15 Ods = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.spreadsheet"), 30)
16
17 Ots = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.spreadsheet-template"), 30)
18
19 Odp = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.presentation"), 30)
20
21 Otp = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.presentation-template"), 30)
22
23 Odg = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.graphics"), 30)
24
25 Otg = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.graphics-template"), 30)
26
27 Odf = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.formula"), 30)
28
29 Odc = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.chart"), 30)
30
31 Epub = offset([]byte("mimetypeapplication/epub+zip"), 30)
32
33 Sxc = offset([]byte("mimetypeapplication/vnd.sun.xml.calc"), 30)
34 )
35
36
37 func Zip(raw []byte, limit uint32) bool {
38 return len(raw) > 3 &&
39 raw[0] == 0x50 && raw[1] == 0x4B &&
40 (raw[2] == 0x3 || raw[2] == 0x5 || raw[2] == 0x7) &&
41 (raw[3] == 0x4 || raw[3] == 0x6 || raw[3] == 0x8)
42 }
43
44
45 func Jar(raw []byte, limit uint32) bool {
46 return zipContains(raw, "META-INF/MANIFEST.MF")
47 }
48
49
50 type zipTokenizer struct {
51 in []byte
52 i int
53 }
54
55
56
57 func (t *zipTokenizer) next() (fileName string) {
58 if t.i > len(t.in) {
59 return
60 }
61 in := t.in[t.i:]
62
63 pkSig := []byte("PK\003\004")
64 pkIndex := bytes.Index(in, pkSig)
65
66 fNameOffset := pkIndex + 30
67
68 if pkIndex == -1 || fNameOffset > len(in) {
69 return
70 }
71
72 fNameLen := int(binary.LittleEndian.Uint16(in[pkIndex+26 : pkIndex+28]))
73 if fNameLen <= 0 || fNameOffset+fNameLen > len(in) {
74 return
75 }
76 t.i += fNameOffset + fNameLen
77 return string(in[fNameOffset : fNameOffset+fNameLen])
78 }
79
80
81 func zipContains(in []byte, paths ...string) bool {
82 t := zipTokenizer{in: in}
83 for i, tok := 0, t.next(); tok != ""; i, tok = i+1, t.next() {
84 for p := range paths {
85 if strings.HasPrefix(tok, paths[p]) {
86 return true
87 }
88 }
89 }
90
91 return false
92 }
93
View as plain text