diff --git a/selfupdate/uncompress.go b/selfupdate/uncompress.go index ba56041..8f461a6 100644 --- a/selfupdate/uncompress.go +++ b/selfupdate/uncompress.go @@ -10,9 +10,32 @@ import ( "io" "io/ioutil" "path/filepath" + "runtime" "strings" ) +func matchExecutableName(cmd, target string) bool { + if cmd == target { + return true + } + + o, a := runtime.GOOS, runtime.GOARCH + + // When the contained executable name is full name (e.g. foo_darwin_amd64), + // it is also regarded as a target executable file. (#19) + for _, d := range []rune{'_', '-'} { + c := fmt.Sprintf("%s%c%s%c%s", cmd, d, o, d, a) + if o == "windows" { + c += ".exe" + } + if c == target { + return true + } + } + + return false +} + func unarchiveTar(src io.Reader, url, cmd string) (io.Reader, error) { t := tar.NewReader(src) for { @@ -24,7 +47,7 @@ func unarchiveTar(src io.Reader, url, cmd string) (io.Reader, error) { return nil, fmt.Errorf("Failed to unarchive .tar file: %s", err) } _, name := filepath.Split(h.Name) - if name == cmd { + if matchExecutableName(cmd, name) { log.Println("Executable file", h.Name, "was found in tar archive") return t, nil } @@ -56,7 +79,7 @@ func UncompressCommand(src io.Reader, url, cmd string) (io.Reader, error) { for _, file := range z.File { _, name := filepath.Split(file.Name) - if !file.FileInfo().IsDir() && name == cmd { + if !file.FileInfo().IsDir() && matchExecutableName(cmd, name) { log.Println("Executable file", file.Name, "was found in zip archive") return file.Open() } @@ -81,7 +104,7 @@ func UncompressCommand(src io.Reader, url, cmd string) (io.Reader, error) { } name := r.Header.Name - if name != cmd { + if !matchExecutableName(cmd, name) { return nil, fmt.Errorf("File name '%s' does not match to command '%s' found in %s", name, cmd, url) } @@ -103,6 +126,7 @@ func UncompressCommand(src io.Reader, url, cmd string) (io.Reader, error) { if err != nil { return nil, fmt.Errorf("Failed to uncompress xzip file downloaded from %s: %s", url, err) } + log.Println("Uncompressed file from xzip is assumed to be an executable", cmd) return xzip, nil }