package platform import ( "archive/zip" "encoding/json" "os" "path/filepath" "testing" "github.com/Eriyc/rules_wails/pkg/wails3kit/updates" ) func TestExtractBundleRejectsTraversal(t *testing.T) { t.Parallel() archivePath := filepath.Join(t.TempDir(), "bundle.zip") file, err := os.Create(archivePath) if err != nil { t.Fatalf("Create returned error: %v", err) } writer := zip.NewWriter(file) entry, err := writer.Create("../escape") if err != nil { t.Fatalf("Create entry returned error: %v", err) } if _, err := entry.Write([]byte("bad")); err != nil { t.Fatalf("Write returned error: %v", err) } if err := writer.Close(); err != nil { t.Fatalf("Close writer returned error: %v", err) } if err := file.Close(); err != nil { t.Fatalf("Close file returned error: %v", err) } if _, _, err := extractBundle(t.Context(), archivePath, updates.ArtifactFormatZip); err == nil { t.Fatal("expected traversal archive to fail") } } func TestApplyBundleReplacesFilesAndPreservesArgs(t *testing.T) { t.Parallel() root := t.TempDir() stage := t.TempDir() if err := os.MkdirAll(filepath.Join(root, "resources"), 0o755); err != nil { t.Fatalf("MkdirAll returned error: %v", err) } if err := os.WriteFile(filepath.Join(root, "App"), []byte("old"), 0o755); err != nil { t.Fatalf("WriteFile returned error: %v", err) } if err := os.WriteFile(filepath.Join(root, "resources", "config.json"), []byte("old"), 0o644); err != nil { t.Fatalf("WriteFile returned error: %v", err) } if err := os.MkdirAll(filepath.Join(stage, "resources"), 0o755); err != nil { t.Fatalf("MkdirAll returned error: %v", err) } if err := os.WriteFile(filepath.Join(stage, "App"), []byte("new"), 0o755); err != nil { t.Fatalf("WriteFile returned error: %v", err) } if err := os.WriteFile(filepath.Join(stage, "resources", "config.json"), []byte("new"), 0o644); err != nil { t.Fatalf("WriteFile returned error: %v", err) } request := helperRequest{ InstallRoot: root, StagedPath: stage, Bundle: updates.BundleManifest{ SchemaVersion: 1, EntryPoint: "App", Files: []updates.BundleFile{ {Path: "App", Mode: "0755"}, {Path: "resources/config.json", Mode: "0644"}, }, }, } if err := applyBundle(request); err != nil { t.Fatalf("applyBundle returned error: %v", err) } bytes, err := os.ReadFile(filepath.Join(root, "App")) if err != nil { t.Fatalf("ReadFile returned error: %v", err) } if string(bytes) != "new" { t.Fatalf("unexpected executable contents: %s", string(bytes)) } bytes, err = os.ReadFile(filepath.Join(root, "resources", "config.json")) if err != nil { t.Fatalf("ReadFile returned error: %v", err) } if string(bytes) != "new" { t.Fatalf("unexpected resource contents: %s", string(bytes)) } } func TestMaybeRunIgnoresNormalArgs(t *testing.T) { t.Parallel() handled, err := MaybeRun([]string{"app"}) if err != nil { t.Fatalf("MaybeRun returned error: %v", err) } if handled { t.Fatal("expected MaybeRun to ignore non-helper args") } } func TestHelperRequestJSONRoundTrip(t *testing.T) { t.Parallel() request := helperRequest{ InstallRoot: "/tmp/app", StagedPath: "/tmp/stage", Bundle: updates.BundleManifest{ SchemaVersion: 1, EntryPoint: "App", Files: []updates.BundleFile{{Path: "App", Mode: "0755"}}, }, Args: []string{"--flag"}, } bytes, err := json.Marshal(request) if err != nil { t.Fatalf("Marshal returned error: %v", err) } var decoded helperRequest if err := json.Unmarshal(bytes, &decoded); err != nil { t.Fatalf("Unmarshal returned error: %v", err) } if decoded.Bundle.EntryPoint != "App" { t.Fatalf("unexpected entrypoint: %s", decoded.Bundle.EntryPoint) } }