gitlab.com/jfprevost/gitlab-runner-notlscheck@v11.11.4+incompatible/helpers/archives/zip_extract.go (about) 1 package archives 2 3 import ( 4 "archive/zip" 5 "io" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 10 "github.com/sirupsen/logrus" 11 ) 12 13 func extractZipDirectoryEntry(file *zip.File) (err error) { 14 err = os.Mkdir(file.Name, file.Mode().Perm()) 15 16 // The error that directory does exists is not a error for us 17 if os.IsExist(err) { 18 err = nil 19 } 20 return 21 } 22 23 func extractZipSymlinkEntry(file *zip.File) (err error) { 24 var data []byte 25 in, err := file.Open() 26 if err != nil { 27 return err 28 } 29 defer in.Close() 30 31 data, err = ioutil.ReadAll(in) 32 if err != nil { 33 return err 34 } 35 36 // Remove symlink before creating a new one, otherwise we can error that file does exist 37 os.Remove(file.Name) 38 err = os.Symlink(string(data), file.Name) 39 return 40 } 41 42 func extractZipFileEntry(file *zip.File) (err error) { 43 var out *os.File 44 in, err := file.Open() 45 if err != nil { 46 return err 47 } 48 defer in.Close() 49 50 // Remove file before creating a new one, otherwise we can error that file does exist 51 os.Remove(file.Name) 52 out, err = os.OpenFile(file.Name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode().Perm()) 53 if err != nil { 54 return err 55 } 56 defer out.Close() 57 _, err = io.Copy(out, in) 58 59 return 60 } 61 62 func extractZipFile(file *zip.File) (err error) { 63 // Create all parents to extract the file 64 os.MkdirAll(filepath.Dir(file.Name), 0777) 65 66 switch file.Mode() & os.ModeType { 67 case os.ModeDir: 68 err = extractZipDirectoryEntry(file) 69 70 case os.ModeSymlink: 71 err = extractZipSymlinkEntry(file) 72 73 case os.ModeNamedPipe, os.ModeSocket, os.ModeDevice: 74 // Ignore the files that of these types 75 logrus.Warningln("File ignored: %q", file.Name) 76 77 default: 78 err = extractZipFileEntry(file) 79 } 80 return 81 } 82 83 func ExtractZipArchive(archive *zip.Reader) error { 84 tracker := newPathErrorTracker() 85 86 for _, file := range archive.File { 87 if err := errorIfGitDirectory(file.Name); tracker.actionable(err) { 88 printGitArchiveWarning("extract") 89 } 90 91 if err := extractZipFile(file); tracker.actionable(err) { 92 logrus.Warningf("%s: %s (suppressing repeats)", file.Name, err) 93 } 94 } 95 96 for _, file := range archive.File { 97 // Update file permissions 98 if err := os.Chmod(file.Name, file.Mode().Perm()); tracker.actionable(err) { 99 logrus.Warningf("%s: %s (suppressing repeats)", file.Name, err) 100 } 101 102 // Process zip metadata 103 if err := processZipExtra(&file.FileHeader); tracker.actionable(err) { 104 logrus.Warningf("%s: %s (suppressing repeats)", file.Name, err) 105 } 106 } 107 108 return nil 109 } 110 111 func ExtractZipFile(fileName string) error { 112 archive, err := zip.OpenReader(fileName) 113 if err != nil { 114 return err 115 } 116 defer archive.Close() 117 118 return ExtractZipArchive(&archive.Reader) 119 }