package release import ( "os" "path/filepath" "strings" "testing" ) func TestStateWritersRefuseSymlinkParents(t *testing.T) { for _, tc := range []struct { name, parent string write func(string) error }{ {"program", "programs", func(dir string) error { return RecordProgram(dir, "app.example", "example.org/app") }}, {"healthy", "healthy", func(dir string) error { return RecordHealthy(dir, "bab", "app", HealthyBuild{SHA256: strings.Repeat("a", 64)}) }}, {"refusal", "refusals", func(dir string) error { return WriteRefusal(dir, Refusal{Host: "app.example"}) }}, } { t.Run(tc.name, func(t *testing.T) { dir, outside := t.TempDir(), t.TempDir() if err := os.Symlink(outside, filepath.Join(dir, tc.parent)); err != nil { t.Fatal(err) } if err := tc.write(dir); err == nil { t.Fatal("write followed a symlink parent") } entries, err := os.ReadDir(outside) if err != nil || len(entries) != 0 { t.Fatalf("outside directory changed: %v %v", entries, err) } }) } } func TestRecordProgramIgnoresPlantedLegacyTemporarySymlink(t *testing.T) { dir := t.TempDir() victim := filepath.Join(dir, "victim") if err := os.WriteFile(victim, []byte("untouched"), 0o600); err != nil { t.Fatal(err) } p := programPath(dir, "app.example") if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil { t.Fatal(err) } if err := os.Symlink(victim, p+".tmp"); err != nil { t.Fatal(err) } if err := RecordProgram(dir, "app.example", "example.org/app"); err != nil { t.Fatal(err) } got, err := os.ReadFile(victim) if err != nil || string(got) != "untouched" { t.Fatalf("victim changed: %q %v", got, err) } if got := ReadPrograms(dir, "app.example"); len(got) != 1 || got[0] != "example.org/app" { t.Fatalf("program not recorded: %v", got) } }