Files
codex-agent-manager/internal/codexhome/bounds_test.go
2026-05-25 16:28:57 +08:00

114 lines
3.0 KiB
Go

package codexhome
import (
"errors"
"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)
}
})
}
}
func TestResolveAgentTOMLRejectsSymlinkToAuthJSON(t *testing.T) {
home := filepath.Join(t.TempDir(), ".codex")
agentsDir := filepath.Join(home, "agents")
if err := os.MkdirAll(agentsDir, 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(home, "auth.json"), []byte("{}"), 0o600); err != nil {
t.Fatal(err)
}
if err := os.Symlink("../auth.json", filepath.Join(agentsDir, "demo.toml")); err != nil {
t.Fatal(err)
}
_, err := ResolveAgentTOML(home, "demo.toml")
if !errors.Is(err, ErrForbiddenPath) {
t.Fatalf("expected ErrForbiddenPath, got %v", err)
}
}