package sync import ( "testing" ) func TestSafeVaultPath(t *testing.T) { tests := []struct { name string vaultRoot string relPath string want string wantErr bool }{ {"empty path", "/tmp/vault", "", "", true}, {"absolute path", "/tmp/vault", "/etc/passwd", "", true}, {"simple escape", "/tmp/vault", "../../etc/passwd", "", true}, {"escape via prefix", "/tmp/vault", "../outside/foo", "", true}, {"clean escape", "/tmp/vault", "a/../../../etc/passwd", "", true}, {"simple file", "/tmp/vault", "file.txt", "file.txt", false}, {"nested file", "/tmp/vault", "a/b/c/file.txt", "a/b/c/file.txt", false}, {"with dots", "/tmp/vault", "a/b/../c/file.txt", "a/c/file.txt", false}, {"unicode path", "/tmp/vault", "проекты/файл.txt", "проекты/файл.txt", false}, {"root level dir", "/tmp/vault", "notes", "notes", false}, {"deeply nested", "/tmp/vault", "clients/acme/projects/website/docs", "clients/acme/projects/website/docs", false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := SafeVaultPath(tt.vaultRoot, tt.relPath) if (err != nil) != tt.wantErr { t.Errorf("SafeVaultPath() error = %v, wantErr = %v", err, tt.wantErr) return } if got != tt.want { t.Errorf("SafeVaultPath() = %q, want %q", got, tt.want) } }) } } func TestSafeVaultPaths(t *testing.T) { vaultRoot := "/tmp/vault" err := SafeVaultPaths(vaultRoot, "a/b", "c/d", "e/f") if err != nil { t.Errorf("SafeVaultPaths() unexpected error: %v", err) } err = SafeVaultPaths(vaultRoot, "a/b", "../../etc/passwd") if err == nil { t.Error("SafeVaultPaths() expected error for escape path, got nil") } err = SafeVaultPaths(vaultRoot) if err != nil { t.Errorf("SafeVaultPaths() with no paths: unexpected error: %v", err) } }