diff --git a/zip.go b/zip.go index 7768b5fb..416fdac9 100644 --- a/zip.go +++ b/zip.go @@ -15,7 +15,7 @@ import ( "github.com/dsnet/compress/bzip2" "github.com/klauspost/compress/zstd" - "github.com/ulikunitz/xz/lzma" + "github.com/ulikunitz/xz" ) // ZipCompressionMethod Compression type @@ -23,12 +23,14 @@ type ZipCompressionMethod uint16 // Compression methods. // see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT. +// Note LZMA: Disabled - because 7z isn't able to unpack ZIP+LZMA ZIP+LZMA2 archives made this way - and vice versa. const ( Store ZipCompressionMethod = 0 Deflate ZipCompressionMethod = 8 BZIP2 ZipCompressionMethod = 12 LZMA ZipCompressionMethod = 14 ZSTD ZipCompressionMethod = 93 + XZ ZipCompressionMethod = 95 ) // Zip provides facilities for operating ZIP archives. @@ -90,32 +92,28 @@ func (*Zip) CheckExt(filename string) error { } // Registering a global decompressor is not reentrant and may panic -func (z *Zip) registerDecompressor() { - if z.decinitialized { - return - } - z.decinitialized = true +func registerDecompressor(zr *zip.Reader) { // register zstd decompressor - z.zr.RegisterDecompressor(uint16(ZSTD), func(r io.Reader) io.ReadCloser { + zr.RegisterDecompressor(uint16(ZSTD), func(r io.Reader) io.ReadCloser { zr, err := zstd.NewReader(r) if err != nil { return nil } return zr.IOReadCloser() }) - z.zr.RegisterDecompressor(uint16(BZIP2), func(r io.Reader) io.ReadCloser { + zr.RegisterDecompressor(uint16(BZIP2), func(r io.Reader) io.ReadCloser { bz2r, err := bzip2.NewReader(r, nil) if err != nil { return nil } return bz2r }) - z.zr.RegisterDecompressor(uint16(LZMA), func(r io.Reader) io.ReadCloser { - lr, err := lzma.NewReader(r) + zr.RegisterDecompressor(uint16(XZ), func(r io.Reader) io.ReadCloser { + xr, err := xz.NewReader(r) if err != nil { return nil } - return ioutil.NopCloser(lr) + return ioutil.NopCloser(xr) }) } @@ -348,14 +346,14 @@ func (z *Zip) Create(out io.Writer) error { z.zw.RegisterCompressor(uint16(BZIP2), func(out io.Writer) (io.WriteCloser, error) { return bzip2.NewWriter(out, &bzip2.WriterConfig{Level: z.CompressionLevel}) }) - case LZMA: - z.zw.RegisterCompressor(uint16(LZMA), func(out io.Writer) (io.WriteCloser, error) { - return lzma.NewWriter(out) - }) case ZSTD: z.zw.RegisterCompressor(uint16(ZSTD), func(out io.Writer) (io.WriteCloser, error) { return zstd.NewWriter(out) }) + case XZ: + z.zw.RegisterCompressor(uint16(XZ), func(out io.Writer) (io.WriteCloser, error) { + return xz.NewWriter(out) + }) } return nil } @@ -441,7 +439,7 @@ func (z *Zip) Open(in io.Reader, size int64) error { if err != nil { return fmt.Errorf("creating reader: %v", err) } - z.registerDecompressor() + registerDecompressor(z.zr) z.ridx = 0 return nil } @@ -498,11 +496,13 @@ func (z *Zip) Walk(archive string, walkFn WalkFunc) error { return fmt.Errorf("opening zip reader: %v", err) } defer zr.Close() - z.registerDecompressor() + registerDecompressor(&zr.Reader) for _, zf := range zr.File { zfrc, err := zf.Open() if err != nil { - zfrc.Close() + if zfrc != nil { + zfrc.Close() + } if z.ContinueOnError { log.Printf("[ERROR] Opening %s: %v", zf.Name, err) continue