fix: use Go archive/tar and archive/zip instead of shelling out

This commit is contained in:
sheeki003 2026-03-23 21:21:53 +05:30
parent 62c5e728a2
commit 6afa676eb1

View file

@ -3,6 +3,9 @@ package tools
import ( import (
"bytes" "bytes"
"context" "context"
"archive/tar"
"archive/zip"
"compress/gzip"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
@ -371,43 +374,71 @@ func tirithExtract(tmpDir, archivePath, ext, binName string) string {
} }
func tirithExtractTarGz(tmpDir, archivePath, binName string) string { func tirithExtractTarGz(tmpDir, archivePath, binName string) string {
cmd := exec.Command("tar", "xzf", archivePath, "-C", tmpDir) f, err := os.Open(archivePath)
if err := cmd.Run(); err != nil { if err != nil {
return "" return ""
} }
// Find the binary defer f.Close()
candidates := []string{
filepath.Join(tmpDir, binName), gz, err := gzip.NewReader(f)
if err != nil {
return ""
} }
for _, c := range candidates { defer gz.Close()
if isExecutable(c) {
return c tr := tar.NewReader(gz)
for {
hdr, err := tr.Next()
if err != nil {
break
}
name := filepath.Base(hdr.Name)
if name == binName && hdr.Typeflag == tar.TypeReg {
dest := filepath.Join(tmpDir, binName)
out, err := os.OpenFile(dest, os.O_CREATE|os.O_WRONLY, 0o755)
if err != nil {
return ""
}
if _, err := io.Copy(out, tr); err != nil {
out.Close()
return ""
}
out.Close()
return dest
} }
} }
// Walk for it return ""
var found string
_ = filepath.Walk(tmpDir, func(path string, info os.FileInfo, err error) error {
if err == nil && info.Name() == binName && !info.IsDir() {
found = path
return filepath.SkipAll
}
return nil
})
return found
} }
func tirithExtractZip(tmpDir, archivePath, binName string) string { func tirithExtractZip(tmpDir, archivePath, binName string) string {
cmd := exec.Command("unzip", "-o", archivePath, "-d", tmpDir) r, err := zip.OpenReader(archivePath)
if err := cmd.Run(); err != nil { if err != nil {
return "" return ""
} }
var found string defer r.Close()
_ = filepath.Walk(tmpDir, func(path string, info os.FileInfo, err error) error {
if err == nil && info.Name() == binName && !info.IsDir() { for _, f := range r.File {
found = path name := filepath.Base(f.Name)
return filepath.SkipAll if name == binName && !f.FileInfo().IsDir() {
rc, err := f.Open()
if err != nil {
return ""
}
dest := filepath.Join(tmpDir, binName)
out, err := os.OpenFile(dest, os.O_CREATE|os.O_WRONLY, 0o755)
if err != nil {
rc.Close()
return ""
}
if _, err := io.Copy(out, rc); err != nil {
out.Close()
rc.Close()
return ""
}
out.Close()
rc.Close()
return dest
} }
return nil }
}) return ""
return found
} }