package runtimelogs import ( "os" "path/filepath" "runtime" "testing" ) func TestValidateFilename(t *testing.T) { valid := []string{"evobgp-all.log", "postgres.log", "bird2.log", "a.log"} for _, name := range valid { if err := ValidateFilename(name); err != nil { t.Fatalf("%q: %v", name, err) } } invalid := []string{"", ".log", "SECRET.log", "../x.log", "x/../y.log", "foo.txt", "a"} for _, name := range invalid { if err := ValidateFilename(name); err == nil { t.Fatalf("expected invalid: %q", name) } } } func TestResolveLogPathTraversal(t *testing.T) { root := t.TempDir() if err := ValidateFilename("ok.log"); err != nil { t.Fatal(err) } okPath := filepath.Join(root, "ok.log") if err := os.WriteFile(okPath, []byte("x"), 0o644); err != nil { t.Fatal(err) } if _, err := ResolveLogPath(root, "ok.log"); err != nil { t.Fatalf("ok.log: %v", err) } if _, err := ResolveLogPath(root, "../etc/passwd"); err == nil { t.Fatal("expected traversal reject") } } func TestResolveLogPathSymlinkEscape(t *testing.T) { if runtime.GOOS == "windows" { t.Skip("symlink root escape test skipped on windows") } root := t.TempDir() outside := t.TempDir() secret := filepath.Join(outside, "secret.log") if err := os.WriteFile(secret, []byte("secret"), 0o644); err != nil { t.Fatal(err) } link := filepath.Join(root, "evil.log") if err := os.Symlink(secret, link); err != nil { t.Skip(err) } if _, err := ResolveLogPath(root, "evil.log"); err == nil { t.Fatal("expected symlink escape to be rejected") } }