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:
parent
7ea7bb0717
commit
50896f203d
2 changed files with 37 additions and 0 deletions
|
|
@ -339,6 +339,14 @@ func (t *ExecTool) guardCommand(command, cwd string) string {
|
||||||
matches := absolutePathPattern.FindAllString(cmd, -1)
|
matches := absolutePathPattern.FindAllString(cmd, -1)
|
||||||
|
|
||||||
for _, raw := range matches {
|
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)
|
p, err := filepath.Abs(raw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
|
|
@ -443,3 +443,32 @@ func TestShellTool_CustomAllowPatterns(t *testing.T) {
|
||||||
t.Errorf("'git push upstream main' should still be blocked by deny pattern")
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue