github.com/weiwenhao/getter@v1.30.1/decompress.go (about)

     1  package getter
     2  
     3  import (
     4  	"os"
     5  	"strings"
     6  )
     7  
     8  // Decompressor defines the interface that must be implemented to add
     9  // support for decompressing a type.
    10  //
    11  // Important: if you're implementing a decompressor, please use the
    12  // containsDotDot helper in this file to ensure that files can't be
    13  // decompressed outside of the specified directory.
    14  type Decompressor interface {
    15  	// Decompress should decompress src to dst. dir specifies whether dst
    16  	// is a directory or single file. src is guaranteed to be a single file
    17  	// that exists. dst is not guaranteed to exist already.
    18  	Decompress(dst, src string, dir bool, umask os.FileMode) error
    19  }
    20  
    21  // Decompressors is the mapping of extension to the Decompressor implementation
    22  // that will decompress that extension/type.
    23  var Decompressors map[string]Decompressor
    24  
    25  func init() {
    26  	tarDecompressor := new(TarDecompressor)
    27  	tbzDecompressor := new(TarBzip2Decompressor)
    28  	tgzDecompressor := new(TarGzipDecompressor)
    29  	txzDecompressor := new(TarXzDecompressor)
    30  	tzstDecompressor := new(TarZstdDecompressor)
    31  
    32  	Decompressors = map[string]Decompressor{
    33  		"bz2":     new(Bzip2Decompressor),
    34  		"gz":      new(GzipDecompressor),
    35  		"xz":      new(XzDecompressor),
    36  		"tar":     tarDecompressor,
    37  		"tar.bz2": tbzDecompressor,
    38  		"tar.gz":  tgzDecompressor,
    39  		"tar.xz":  txzDecompressor,
    40  		"tar.zst": tzstDecompressor,
    41  		"tbz2":    tbzDecompressor,
    42  		"tgz":     tgzDecompressor,
    43  		"txz":     txzDecompressor,
    44  		"tzst":    tzstDecompressor,
    45  		"zip":     new(ZipDecompressor),
    46  		"zst":     new(ZstdDecompressor),
    47  	}
    48  }
    49  
    50  // containsDotDot checks if the filepath value v contains a ".." entry.
    51  // This will check filepath components by splitting along / or \. This
    52  // function is copied directly from the Go net/http implementation.
    53  func containsDotDot(v string) bool {
    54  	if !strings.Contains(v, "..") {
    55  		return false
    56  	}
    57  	for _, ent := range strings.FieldsFunc(v, isSlashRune) {
    58  		if ent == ".." {
    59  			return true
    60  		}
    61  	}
    62  	return false
    63  }
    64  
    65  func isSlashRune(r rune) bool { return r == '/' || r == '\\' }