fix: fix conflicts
This commit is contained in:
parent
70b4dffaa6
commit
389a40bf81
1 changed files with 79 additions and 21 deletions
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -88,14 +89,12 @@ type ReadFileTool struct {
|
||||||
fs fileSystem
|
fs fileSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewReadFileTool(workspace string, restrict bool) *ReadFileTool {
|
func NewReadFileTool(workspace string, restrict bool, allowPaths ...[]*regexp.Regexp) *ReadFileTool {
|
||||||
var fs fileSystem
|
var patterns []*regexp.Regexp
|
||||||
if restrict {
|
if len(allowPaths) > 0 {
|
||||||
fs = &sandboxFs{workspace: workspace}
|
patterns = allowPaths[0]
|
||||||
} else {
|
|
||||||
fs = &hostFs{}
|
|
||||||
}
|
}
|
||||||
return &ReadFileTool{fs: fs}
|
return &ReadFileTool{fs: buildFs(workspace, restrict, patterns)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ReadFileTool) Name() string {
|
func (t *ReadFileTool) Name() string {
|
||||||
|
|
@ -142,14 +141,12 @@ type WriteFileTool struct {
|
||||||
fs fileSystem
|
fs fileSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWriteFileTool(workspace string, restrict bool) *WriteFileTool {
|
func NewWriteFileTool(workspace string, restrict bool, allowPaths ...[]*regexp.Regexp) *WriteFileTool {
|
||||||
var fs fileSystem
|
var patterns []*regexp.Regexp
|
||||||
if restrict {
|
if len(allowPaths) > 0 {
|
||||||
fs = &sandboxFs{workspace: workspace}
|
patterns = allowPaths[0]
|
||||||
} else {
|
|
||||||
fs = &hostFs{}
|
|
||||||
}
|
}
|
||||||
return &WriteFileTool{fs: fs}
|
return &WriteFileTool{fs: buildFs(workspace, restrict, patterns)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *WriteFileTool) Name() string {
|
func (t *WriteFileTool) Name() string {
|
||||||
|
|
@ -205,14 +202,12 @@ type ListDirTool struct {
|
||||||
fs fileSystem
|
fs fileSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewListDirTool(workspace string, restrict bool) *ListDirTool {
|
func NewListDirTool(workspace string, restrict bool, allowPaths ...[]*regexp.Regexp) *ListDirTool {
|
||||||
var fs fileSystem
|
var patterns []*regexp.Regexp
|
||||||
if restrict {
|
if len(allowPaths) > 0 {
|
||||||
fs = &sandboxFs{workspace: workspace}
|
patterns = allowPaths[0]
|
||||||
} else {
|
|
||||||
fs = &hostFs{}
|
|
||||||
}
|
}
|
||||||
return &ListDirTool{fs: fs}
|
return &ListDirTool{fs: buildFs(workspace, restrict, patterns)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ListDirTool) Name() string {
|
func (t *ListDirTool) Name() string {
|
||||||
|
|
@ -482,6 +477,69 @@ func (r *sandboxFs) ReadDir(path string) ([]os.DirEntry, error) {
|
||||||
return entries, err
|
return entries, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// whitelistFs wraps a sandboxFs and allows access to specific paths outside
|
||||||
|
// the workspace when they match any of the provided patterns.
|
||||||
|
type whitelistFs struct {
|
||||||
|
sandbox *sandboxFs
|
||||||
|
host hostFs
|
||||||
|
patterns []*regexp.Regexp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *whitelistFs) matches(path string) bool {
|
||||||
|
for _, p := range w.patterns {
|
||||||
|
if p.MatchString(path) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *whitelistFs) ReadFile(path string) ([]byte, error) {
|
||||||
|
if w.matches(path) {
|
||||||
|
return w.host.ReadFile(path)
|
||||||
|
}
|
||||||
|
return w.sandbox.ReadFile(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *whitelistFs) WriteFile(path string, data []byte) error {
|
||||||
|
if w.matches(path) {
|
||||||
|
return w.host.WriteFile(path, data)
|
||||||
|
}
|
||||||
|
return w.sandbox.WriteFile(path, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *whitelistFs) ReadDir(path string) ([]os.DirEntry, error) {
|
||||||
|
if w.matches(path) {
|
||||||
|
return w.host.ReadDir(path)
|
||||||
|
}
|
||||||
|
return w.sandbox.ReadDir(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *whitelistFs) EditFile(path string, editFn func([]byte) ([]byte, error)) error {
|
||||||
|
content, err := w.ReadFile(path)
|
||||||
|
if err != nil && !os.IsNotExist(err) {
|
||||||
|
return fmt.Errorf("failed to read file for editing: %w", err)
|
||||||
|
}
|
||||||
|
newContent, err := editFn(content)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return w.WriteFile(path, newContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// buildFs returns the appropriate fileSystem implementation based on restriction
|
||||||
|
// settings and optional path whitelist patterns.
|
||||||
|
func buildFs(workspace string, restrict bool, patterns []*regexp.Regexp) fileSystem {
|
||||||
|
if !restrict {
|
||||||
|
return &hostFs{}
|
||||||
|
}
|
||||||
|
sandbox := &sandboxFs{workspace: workspace}
|
||||||
|
if len(patterns) > 0 {
|
||||||
|
return &whitelistFs{sandbox: sandbox, patterns: patterns}
|
||||||
|
}
|
||||||
|
return sandbox
|
||||||
|
}
|
||||||
|
|
||||||
// Helper to get a safe relative path for os.Root usage
|
// Helper to get a safe relative path for os.Root usage
|
||||||
func getSafeRelPath(workspace, path string) (string, error) {
|
func getSafeRelPath(workspace, path string) (string, error) {
|
||||||
if workspace == "" {
|
if workspace == "" {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue