]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/go-getter/decompress_zip.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / go-getter / decompress_zip.go
1 package getter
2
3 import (
4 "archive/zip"
5 "fmt"
6 "io"
7 "os"
8 "path/filepath"
9 )
10
11 // ZipDecompressor is an implementation of Decompressor that can
12 // decompress zip files.
13 type ZipDecompressor struct{}
14
15 func (d *ZipDecompressor) Decompress(dst, src string, dir bool) error {
16 // If we're going into a directory we should make that first
17 mkdir := dst
18 if !dir {
19 mkdir = filepath.Dir(dst)
20 }
21 if err := os.MkdirAll(mkdir, 0755); err != nil {
22 return err
23 }
24
25 // Open the zip
26 zipR, err := zip.OpenReader(src)
27 if err != nil {
28 return err
29 }
30 defer zipR.Close()
31
32 // Check the zip integrity
33 if len(zipR.File) == 0 {
34 // Empty archive
35 return fmt.Errorf("empty archive: %s", src)
36 }
37 if !dir && len(zipR.File) > 1 {
38 return fmt.Errorf("expected a single file: %s", src)
39 }
40
41 // Go through and unarchive
42 for _, f := range zipR.File {
43 path := dst
44 if dir {
45 // Disallow parent traversal
46 if containsDotDot(f.Name) {
47 return fmt.Errorf("entry contains '..': %s", f.Name)
48 }
49
50 path = filepath.Join(path, f.Name)
51 }
52
53 if f.FileInfo().IsDir() {
54 if !dir {
55 return fmt.Errorf("expected a single file: %s", src)
56 }
57
58 // A directory, just make the directory and continue unarchiving...
59 if err := os.MkdirAll(path, 0755); err != nil {
60 return err
61 }
62
63 continue
64 }
65
66 // Create the enclosing directories if we must. ZIP files aren't
67 // required to contain entries for just the directories so this
68 // can happen.
69 if dir {
70 if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
71 return err
72 }
73 }
74
75 // Open the file for reading
76 srcF, err := f.Open()
77 if err != nil {
78 return err
79 }
80
81 // Open the file for writing
82 dstF, err := os.Create(path)
83 if err != nil {
84 srcF.Close()
85 return err
86 }
87 _, err = io.Copy(dstF, srcF)
88 srcF.Close()
89 dstF.Close()
90 if err != nil {
91 return err
92 }
93
94 // Chmod the file
95 if err := os.Chmod(path, f.Mode()); err != nil {
96 return err
97 }
98 }
99
100 return nil
101 }