diff --git a/pkg/tools/edit_test.go b/pkg/tools/edit_test.go index 6406302f9..83a7e778c 100644 --- a/pkg/tools/edit_test.go +++ b/pkg/tools/edit_test.go @@ -158,8 +158,13 @@ func TestEditTool_EditFile_OutsideAllowedDir(t *testing.T) { // Should mention outside allowed directory // Note: ErrorResult only sets ForLLM by default, so ForUser might be empty. // We check ForLLM as it's the primary error channel. - assert.True(t, strings.Contains(result.ForLLM, "outside") || strings.Contains(result.ForLLM, "access denied") || strings.Contains(result.ForLLM, "escapes"), - "Expected 'outside allowed' or 'access denied' message, got ForLLM: %s", result.ForLLM) + assert.True( + t, + strings.Contains(result.ForLLM, "outside") || strings.Contains(result.ForLLM, "access denied") || + strings.Contains(result.ForLLM, "escapes"), + "Expected 'outside allowed' or 'access denied' message, got ForLLM: %s", + result.ForLLM, + ) } // TestEditTool_EditFile_MissingPath verifies error handling for missing path @@ -346,13 +351,18 @@ func TestAppendFileTool_AppendToNonExistent_Restricted(t *testing.T) { tool := NewAppendFileTool(workspace, true) ctx := context.Background() - args := map[string]interface{}{ + args := map[string]any{ "path": "brand_new_file.txt", "content": "first content", } result := tool.Execute(ctx, args) - assert.False(t, result.IsError, "Expected success when appending to non-existent file in restricted mode, got: %s", result.ForLLM) + assert.False( + t, + result.IsError, + "Expected success when appending to non-existent file in restricted mode, got: %s", + result.ForLLM, + ) // Verify the file was created with correct content data, err := os.ReadFile(filepath.Join(workspace, "brand_new_file.txt")) @@ -365,12 +375,12 @@ func TestAppendFileTool_AppendToNonExistent_Restricted(t *testing.T) { func TestAppendFileTool_Restricted_Success(t *testing.T) { workspace := t.TempDir() testFile := "existing.txt" - err := os.WriteFile(filepath.Join(workspace, testFile), []byte("initial"), 0644) + err := os.WriteFile(filepath.Join(workspace, testFile), []byte("initial"), 0o644) assert.NoError(t, err) tool := NewAppendFileTool(workspace, true) ctx := context.Background() - args := map[string]interface{}{ + args := map[string]any{ "path": testFile, "content": " appended", } @@ -389,12 +399,12 @@ func TestAppendFileTool_Restricted_Success(t *testing.T) { func TestEditFileTool_Restricted_InPlaceEdit(t *testing.T) { workspace := t.TempDir() testFile := "edit_target.txt" - err := os.WriteFile(filepath.Join(workspace, testFile), []byte("Hello World"), 0644) + err := os.WriteFile(filepath.Join(workspace, testFile), []byte("Hello World"), 0o644) assert.NoError(t, err) tool := NewEditFileTool(workspace, true) ctx := context.Background() - args := map[string]interface{}{ + args := map[string]any{ "path": testFile, "old_text": "World", "new_text": "Go", @@ -415,7 +425,7 @@ func TestEditFileTool_Restricted_FileNotFound(t *testing.T) { workspace := t.TempDir() tool := NewEditFileTool(workspace, true) ctx := context.Background() - args := map[string]interface{}{ + args := map[string]any{ "path": "no_such_file.txt", "old_text": "old", "new_text": "new", diff --git a/pkg/tools/filesystem.go b/pkg/tools/filesystem.go index d713aebf5..de473264e 100644 --- a/pkg/tools/filesystem.go +++ b/pkg/tools/filesystem.go @@ -277,7 +277,7 @@ func (h *hostFs) ReadDir(path string) ([]os.DirEntry, error) { func (h *hostFs) WriteFile(path string, data []byte) error { dir := filepath.Dir(path) - if err := os.MkdirAll(dir, 0755); err != nil { + if err := os.MkdirAll(dir, 0o755); err != nil { return fmt.Errorf("failed to create parent directories: %w", err) } @@ -285,7 +285,7 @@ func (h *hostFs) WriteFile(path string, data []byte) error { // This prevents the target file from being left in a truncated or partial state // if the operation is interrupted, as the rename operation is atomic on Linux. tmpPath := fmt.Sprintf("%s.%d.tmp", path, time.Now().UnixNano()) - if err := os.WriteFile(tmpPath, data, 0644); err != nil { + if err := os.WriteFile(tmpPath, data, 0o644); err != nil { os.Remove(tmpPath) // Ensure cleanup of partial/empty temp file return fmt.Errorf("failed to write temp file: %w", err) } @@ -330,7 +330,8 @@ func (r *sandboxFs) ReadFile(path string) ([]byte, error) { return fmt.Errorf("failed to read file: file not found: %w", err) } // os.Root returns "escapes from parent" for paths outside the root - if os.IsPermission(err) || strings.Contains(err.Error(), "escapes from parent") || strings.Contains(err.Error(), "permission denied") { + if os.IsPermission(err) || strings.Contains(err.Error(), "escapes from parent") || + strings.Contains(err.Error(), "permission denied") { return fmt.Errorf("failed to read file: access denied: %w", err) } return fmt.Errorf("failed to read file: %w", err) @@ -345,7 +346,7 @@ func (r *sandboxFs) WriteFile(path string, data []byte) error { return r.execute(path, func(root *os.Root, relPath string) error { dir := filepath.Dir(relPath) if dir != "." && dir != "/" { - if err := root.MkdirAll(dir, 0755); err != nil { + if err := root.MkdirAll(dir, 0o755); err != nil { return fmt.Errorf("failed to create parent directories: %w", err) } } @@ -355,7 +356,7 @@ func (r *sandboxFs) WriteFile(path string, data []byte) error { // if the operation is interrupted, as the rename operation is atomic on Linux. tmpRelPath := fmt.Sprintf("%s.%d.tmp", relPath, time.Now().UnixNano()) - if err := root.WriteFile(tmpRelPath, data, 0644); err != nil { + if err := root.WriteFile(tmpRelPath, data, 0o644); err != nil { root.Remove(tmpRelPath) // Ensure cleanup of partial/empty temp file return fmt.Errorf("failed to write to temp file: %w", err) } diff --git a/pkg/tools/filesystem_test.go b/pkg/tools/filesystem_test.go index 1687ca395..6f896e22d 100644 --- a/pkg/tools/filesystem_test.go +++ b/pkg/tools/filesystem_test.go @@ -281,7 +281,8 @@ func TestFilesystemTool_ReadFile_RejectsSymlinkEscape(t *testing.T) { // os.Root might return different errors depending on platform/implementation // but it definitely should error. // Our wrapper returns "access denied or file not found" - if !strings.Contains(result.ForLLM, "access denied") && !strings.Contains(result.ForLLM, "file not found") && !strings.Contains(result.ForLLM, "no such file") { + if !strings.Contains(result.ForLLM, "access denied") && !strings.Contains(result.ForLLM, "file not found") && + !strings.Contains(result.ForLLM, "no such file") { t.Fatalf("expected symlink escape error, got: %s", result.ForLLM) } } @@ -292,7 +293,7 @@ func TestFilesystemTool_EmptyWorkspace_AccessDenied(t *testing.T) { // Try to read a sensitive file (simulated by a temp file outside workspace) tmpDir := t.TempDir() secretFile := filepath.Join(tmpDir, "shadow") - os.WriteFile(secretFile, []byte("secret data"), 0600) + os.WriteFile(secretFile, []byte("secret data"), 0o600) result := tool.Execute(context.Background(), map[string]any{ "path": secretFile, @@ -316,25 +317,25 @@ func TestRootMkdirAll(t *testing.T) { defer root.Close() // Case 1: Single directory - err = root.MkdirAll("dir1", 0755) + err = root.MkdirAll("dir1", 0o755) assert.NoError(t, err) _, err = os.Stat(filepath.Join(workspace, "dir1")) assert.NoError(t, err) // Case 2: Deeply nested directory - err = root.MkdirAll("a/b/c/d", 0755) + err = root.MkdirAll("a/b/c/d", 0o755) assert.NoError(t, err) _, err = os.Stat(filepath.Join(workspace, "a/b/c/d")) assert.NoError(t, err) // Case 3: Already exists — must be idempotent - err = root.MkdirAll("a/b/c/d", 0755) + err = root.MkdirAll("a/b/c/d", 0o755) assert.NoError(t, err) // Case 4: A regular file blocks directory creation — must error - err = os.WriteFile(filepath.Join(workspace, "file_exists"), []byte("data"), 0644) + err = os.WriteFile(filepath.Join(workspace, "file_exists"), []byte("data"), 0o644) assert.NoError(t, err) - err = root.MkdirAll("file_exists", 0755) + err = root.MkdirAll("file_exists", 0o755) assert.Error(t, err, "expected error when a file exists at the directory path") } @@ -367,9 +368,9 @@ func TestHostRW_Read_PermissionDenied(t *testing.T) { } tmpDir := t.TempDir() protected := filepath.Join(tmpDir, "protected.txt") - err := os.WriteFile(protected, []byte("secret"), 0000) + err := os.WriteFile(protected, []byte("secret"), 0o000) assert.NoError(t, err) - defer os.Chmod(protected, 0644) // ensure cleanup + defer os.Chmod(protected, 0o644) // ensure cleanup _, err = (&hostFs{}).ReadFile(protected) assert.Error(t, err) @@ -392,7 +393,7 @@ func TestRootRW_Read_Directory(t *testing.T) { defer root.Close() // Create a subdirectory - err = root.Mkdir("subdir", 0755) + err = root.Mkdir("subdir", 0o755) assert.NoError(t, err) _, err = (&sandboxFs{workspace: workspace}).ReadFile("subdir")