package codexhome import ( "os" "path/filepath" "testing" ) func TestResolveInsideCodexHomeAllowsAgentsToml(t *testing.T) { home := filepath.Join(t.TempDir(), ".codex") got, err := ResolveInside(home, "agents/product-manager.toml") if err != nil { t.Fatalf("ResolveInside returned error: %v", err) } want := filepath.Join(home, "agents", "product-manager.toml") if got != want { t.Fatalf("path mismatch: got %q want %q", got, want) } } func TestResolveInsideCodexHomeRejectsTraversal(t *testing.T) { home := filepath.Join(t.TempDir(), ".codex") _, err := ResolveInside(home, "../auth.json") if err == nil { t.Fatal("expected traversal to be rejected") } } func TestResolveInsideCodexHomeRejectsSymlinkEscape(t *testing.T) { root := t.TempDir() home := filepath.Join(root, ".codex") external := filepath.Join(root, "external") if err := os.MkdirAll(home, 0o755); err != nil { t.Fatal(err) } if err := os.MkdirAll(external, 0o755); err != nil { t.Fatal(err) } if err := os.Symlink(external, filepath.Join(home, "agents")); err != nil { t.Fatal(err) } _, err := ResolveInside(home, "agents/x.toml") if err == nil { t.Fatal("expected symlink escape to be rejected") } } func TestIsForbiddenPathBlocksAuthJSON(t *testing.T) { home := filepath.Join(t.TempDir(), ".codex") path := filepath.Join(home, "auth.json") if !IsForbidden(path, home) { t.Fatal("auth.json must be forbidden") } } func TestResolveInsideCodexHomeBlocksAuthJSONCaseInsensitive(t *testing.T) { home := filepath.Join(t.TempDir(), ".codex") _, err := ResolveInside(home, "AUTH.JSON") if err == nil { t.Fatal("AUTH.JSON must be forbidden") } } func TestResolveAgentTOMLAllowsDirectAgentToml(t *testing.T) { home := filepath.Join(t.TempDir(), ".codex") got, err := ResolveAgentTOML(home, "product-manager.toml") if err != nil { t.Fatalf("ResolveAgentTOML returned error: %v", err) } want := filepath.Join(home, "agents", "product-manager.toml") if got != want { t.Fatalf("path mismatch: got %q want %q", got, want) } } func TestResolveAgentTOMLRejectsUnsafeNames(t *testing.T) { tests := []string{ "../auth.json", "auth.json", "sessions/demo.jsonl", "nested/demo.toml", "demo.txt", } home := filepath.Join(t.TempDir(), ".codex") for _, tt := range tests { t.Run(tt, func(t *testing.T) { _, err := ResolveAgentTOML(home, tt) if err == nil { t.Fatalf("expected %q to be rejected", tt) } }) } }