127 lines
3.2 KiB
Go
127 lines
3.2 KiB
Go
package scoutpkg
|
|
|
|
import (
|
|
"archive/zip"
|
|
"bytes"
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestNormalizeAndMatchTarget(t *testing.T) {
|
|
targets := []Target{
|
|
{Platform: "any", Architecture: "universal", Path: "targets/all"},
|
|
{Platform: "linux", Architecture: "universal", Path: "targets/linux"},
|
|
{Platform: "linux", Architecture: "amd64", Path: "targets/linux-amd64"},
|
|
}
|
|
target, ok := MatchTarget(targets, "linux", "x86_64")
|
|
if !ok || target.Path != "targets/linux-amd64" {
|
|
t.Fatalf("目标匹配错误: %+v", target)
|
|
}
|
|
target, ok = MatchTarget(targets, "linux", "arm64")
|
|
if !ok || target.Path != "targets/linux" {
|
|
t.Fatalf("通用目标匹配错误: %+v", target)
|
|
}
|
|
}
|
|
|
|
func TestOpenAndExtract(t *testing.T) {
|
|
archivePath := filepath.Join(t.TempDir(), "demo.scout")
|
|
manifest := Manifest{
|
|
SchemaVersion: 1,
|
|
Name: "demo-core",
|
|
Version: "1.2.0",
|
|
Channel: "stable",
|
|
PackageType: "full",
|
|
Targets: []Target{{
|
|
Platform: "linux",
|
|
Architecture: "amd64",
|
|
Path: "targets/linux/amd64",
|
|
Entrypoint: "targets/linux/amd64/demo",
|
|
}},
|
|
}
|
|
createArchive(t, archivePath, manifest, map[string][]byte{
|
|
"targets/linux/amd64/demo": []byte("binary"),
|
|
})
|
|
archive, err := Open(archivePath)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer archive.Close()
|
|
destination := filepath.Join(t.TempDir(), "release")
|
|
target, err := archive.Extract("linux", "amd64", destination)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if target.Entrypoint != "targets/linux/amd64/demo" {
|
|
t.Fatalf("启动入口错误: %s", target.Entrypoint)
|
|
}
|
|
content, err := os.ReadFile(filepath.Join(destination, "demo"))
|
|
if err != nil || string(content) != "binary" {
|
|
t.Fatalf("解压结果错误: %q, %v", content, err)
|
|
}
|
|
}
|
|
|
|
func TestRejectsPathTraversal(t *testing.T) {
|
|
archivePath := filepath.Join(t.TempDir(), "unsafe.scout")
|
|
buffer := bytes.NewBuffer(nil)
|
|
writer := zip.NewWriter(buffer)
|
|
manifest := Manifest{
|
|
SchemaVersion: 1,
|
|
Name: "unsafe",
|
|
Version: "1.0.0",
|
|
Targets: []Target{{
|
|
Platform: "linux",
|
|
Architecture: "amd64",
|
|
Path: "targets/linux/amd64",
|
|
}},
|
|
}
|
|
manifestData, _ := json.Marshal(manifest)
|
|
entry, _ := writer.Create(ManifestName)
|
|
_, _ = entry.Write(manifestData)
|
|
entry, _ = writer.Create("../escape")
|
|
_, _ = entry.Write([]byte("unsafe"))
|
|
_ = writer.Close()
|
|
if err := os.WriteFile(archivePath, buffer.Bytes(), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := Open(archivePath); err == nil {
|
|
t.Fatal("路径穿越包没有被拒绝")
|
|
}
|
|
}
|
|
|
|
func createArchive(t *testing.T, fileName string, manifest Manifest, files map[string][]byte) {
|
|
t.Helper()
|
|
output, err := os.Create(fileName)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
writer := zip.NewWriter(output)
|
|
manifestData, err := json.Marshal(manifest)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
entry, err := writer.Create(ManifestName)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := entry.Write(manifestData); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for name, content := range files {
|
|
entry, err := writer.Create(name)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := entry.Write(content); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if err := writer.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := output.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|