| 163 | } |
| 164 | |
| 165 | func archiveItem(zipWriter *zip.Writer, sourcePath, archivePath string, info os.FileInfo, totalSize *int64, uid int, gid int) error { |
| 166 | if !IsSafePath(sourcePath) { |
| 167 | return fmt.Errorf("security risk: wrong filepath") |
| 168 | } |
| 169 | |
| 170 | header, err := zip.FileInfoHeader(info) |
| 171 | if err != nil { |
| 172 | return fmt.Errorf("cannot create zip header: %v", err) |
| 173 | } |
| 174 | |
| 175 | header.Name = archivePath |
| 176 | |
| 177 | if info.IsDir() { |
| 178 | header.Name += "/" |
| 179 | } else { |
| 180 | header.Method = zip.Deflate |
| 181 | } |
| 182 | |
| 183 | writer, err := zipWriter.CreateHeader(header) |
| 184 | if err != nil { |
| 185 | return fmt.Errorf("cannot create zip entry: %v", err) |
| 186 | } |
| 187 | |
| 188 | if info.IsDir() { |
| 189 | return nil |
| 190 | } |
| 191 | |
| 192 | sourceFile, err := os.Open(sourcePath) |
| 193 | if err != nil { |
| 194 | return fmt.Errorf("cannot open source file: %v", err) |
| 195 | } |
| 196 | defer sourceFile.Close() |
| 197 | |
| 198 | size, err := io.Copy(writer, sourceFile) |
| 199 | if err != nil { |
| 200 | return fmt.Errorf("cannot copy file content: %v", err) |
| 201 | } |
| 202 | |
| 203 | *totalSize += size |
| 204 | return nil |
| 205 | } |