fix: safety guard incorrectly blocks commands with URLs

The absolutePathPattern regex was matching URL path components like
//github.com as file system paths, causing commands containing URLs
to be incorrectly blocked by the workspace restriction safety guard.

For example, 'agent-browser open https://github.com' would be blocked
because //github.com was treated as an absolute file path outside
the working directory.

The fix adds a check to skip any path match that starts with '//',
as these are URL path components, not file system paths.

Fixes #1203
This commit is contained in:
Hakancan 2026-03-08 23:01:02 +00:00
parent 7ea7bb0717
commit 50896f203d
2 changed files with 37 additions and 0 deletions

View file

@ -339,6 +339,14 @@ func (t *ExecTool) guardCommand(command, cwd string) string {
matches := absolutePathPattern.FindAllString(cmd, -1)
for _, raw := range matches {
// Skip URL path components that look like they're from URLs.
// When a URL like "https://github.com" is parsed, the regex captures
// "//github.com" as a match (the path portion after "https:").
// These double-slash prefixes indicate URL paths, not file system paths.
if strings.HasPrefix(raw, "//") {
continue
}
p, err := filepath.Abs(raw)
if err != nil {
continue

View file

@ -443,3 +443,32 @@ func TestShellTool_CustomAllowPatterns(t *testing.T) {
t.Errorf("'git push upstream main' should still be blocked by deny pattern")
}
}
// TestShellTool_URLsNotBlocked verifies that commands containing URLs are not
// incorrectly blocked by the workspace restriction safety guard (issue #1203).
func TestShellTool_URLsNotBlocked(t *testing.T) {
tmpDir := t.TempDir()
tool, err := NewExecTool(tmpDir, true)
if err != nil {
t.Fatalf("unable to configure exec tool: %s", err)
}
// These commands contain URLs and should NOT be blocked by workspace restriction.
// The URL path components (e.g., "//github.com") should be recognized as URLs,
// not as file system paths.
commands := []string{
"agent-browser open https://github.com",
"curl https://api.example.com/data",
"wget http://example.com/file",
"browser open https://github.com/user/repo",
"fetch ftp://ftp.example.com/file.txt",
"git clone https://github.com/sipeed/picoclaw.git",
}
for _, cmd := range commands {
result := tool.Execute(context.Background(), map[string]any{"command": cmd})
if result.IsError && strings.Contains(result.ForLLM, "path outside working dir") {
t.Errorf("command with URL should not be blocked by workspace check: %s\n error: %s", cmd, result.ForLLM)
}
}
}