(dir string, r io.Reader, stripPathComponents int)
| 125 | } |
| 126 | |
| 127 | func unzip(dir string, r io.Reader, stripPathComponents int) error { |
| 128 | if err := os.MkdirAll(dir, dirMode); err != nil { |
| 129 | return errors.Wrapf(err, "error creating output directory %q", dir) |
| 130 | } |
| 131 | |
| 132 | outDir, err := os.OpenRoot(dir) |
| 133 | if err != nil { |
| 134 | return errors.Wrapf(err, "could not open output directory root %q", dir) |
| 135 | } |
| 136 | |
| 137 | defer outDir.Close() //nolint:errcheck |
| 138 | |
| 139 | // zips require ReaderAt, most installers are quite small so we'll just buffer them in memory |
| 140 | var buf bytes.Buffer |
| 141 | if _, err := io.Copy(&buf, r); err != nil { |
| 142 | return errors.Wrap(err, "error reading zip file") |
| 143 | } |
| 144 | |
| 145 | readerAt := bytes.NewReader(buf.Bytes()) |
| 146 | |
| 147 | zf, zerr := zip.NewReader(readerAt, int64(buf.Len())) |
| 148 | if zerr != nil { |
| 149 | return errors.Wrap(zerr, "unable to open zip") |
| 150 | } |
| 151 | |
| 152 | for _, f := range zf.File { |
| 153 | fpath, ok := stripLeadingPath(f.Name, stripPathComponents) |
| 154 | if !ok { |
| 155 | continue |
| 156 | } |
| 157 | |
| 158 | if err := outDir.MkdirAll(filepath.Dir(fpath), dirMode); err != nil { |
| 159 | return errors.Wrap(err, "error creating parent directory") |
| 160 | } |
| 161 | |
| 162 | switch f.FileInfo().Mode() & os.ModeType { |
| 163 | case os.ModeDir: |
| 164 | if err := outDir.MkdirAll(fpath, dirMode); err != nil { |
| 165 | return errors.Wrap(err, "error creating directory") |
| 166 | } |
| 167 | |
| 168 | continue |
| 169 | |
| 170 | case 0: |
| 171 | fc, err := f.Open() |
| 172 | if err != nil { |
| 173 | return errors.Wrap(err, "error opening zip entry") |
| 174 | } |
| 175 | |
| 176 | if ferr := createFile(outDir, fpath, f.FileInfo().Mode(), f.FileInfo().ModTime(), fc); ferr != nil { |
| 177 | return errors.Wrapf(ferr, "error creating file %v", f.Name) |
| 178 | } |
| 179 | |
| 180 | fc.Close() //nolint:errcheck |
| 181 | |
| 182 | default: |
| 183 | return errors.Errorf("unsupported zip entry %v: %v", f.Name, f.FileInfo().Mode()) |
| 184 | } |
no test coverage detected