]>
Commit | Line | Data |
---|---|---|
bae9f6d2 JC |
1 | package getter |
2 | ||
15c0b25d AP |
3 | import ( |
4 | "strings" | |
5 | ) | |
6 | ||
bae9f6d2 JC |
7 | // Decompressor defines the interface that must be implemented to add |
8 | // support for decompressing a type. | |
15c0b25d AP |
9 | // |
10 | // Important: if you're implementing a decompressor, please use the | |
11 | // containsDotDot helper in this file to ensure that files can't be | |
12 | // decompressed outside of the specified directory. | |
bae9f6d2 JC |
13 | type Decompressor interface { |
14 | // Decompress should decompress src to dst. dir specifies whether dst | |
15 | // is a directory or single file. src is guaranteed to be a single file | |
16 | // that exists. dst is not guaranteed to exist already. | |
17 | Decompress(dst, src string, dir bool) error | |
18 | } | |
19 | ||
20 | // Decompressors is the mapping of extension to the Decompressor implementation | |
21 | // that will decompress that extension/type. | |
22 | var Decompressors map[string]Decompressor | |
23 | ||
24 | func init() { | |
25 | tbzDecompressor := new(TarBzip2Decompressor) | |
26 | tgzDecompressor := new(TarGzipDecompressor) | |
15c0b25d | 27 | txzDecompressor := new(TarXzDecompressor) |
bae9f6d2 JC |
28 | |
29 | Decompressors = map[string]Decompressor{ | |
30 | "bz2": new(Bzip2Decompressor), | |
31 | "gz": new(GzipDecompressor), | |
15c0b25d | 32 | "xz": new(XzDecompressor), |
bae9f6d2 JC |
33 | "tar.bz2": tbzDecompressor, |
34 | "tar.gz": tgzDecompressor, | |
15c0b25d | 35 | "tar.xz": txzDecompressor, |
bae9f6d2 JC |
36 | "tbz2": tbzDecompressor, |
37 | "tgz": tgzDecompressor, | |
15c0b25d | 38 | "txz": txzDecompressor, |
bae9f6d2 JC |
39 | "zip": new(ZipDecompressor), |
40 | } | |
41 | } | |
15c0b25d AP |
42 | |
43 | // containsDotDot checks if the filepath value v contains a ".." entry. | |
44 | // This will check filepath components by splitting along / or \. This | |
45 | // function is copied directly from the Go net/http implementation. | |
46 | func containsDotDot(v string) bool { | |
47 | if !strings.Contains(v, "..") { | |
48 | return false | |
49 | } | |
50 | for _, ent := range strings.FieldsFunc(v, isSlashRune) { | |
51 | if ent == ".." { | |
52 | return true | |
53 | } | |
54 | } | |
55 | return false | |
56 | } | |
57 | ||
58 | func isSlashRune(r rune) bool { return r == '/' || r == '\\' } |