| 1302 | resolved := resolvePathBestEffort(path) |
| 1303 | for _, root := range roots { |
| 1304 | absRoot := resolvePathBestEffort(root) |
| 1305 | rel, err := filepath.Rel(absRoot, resolved) |
| 1306 | if err == nil && rel != ".." && !strings.HasPrefix(rel, ".."+string(filepath.Separator)) { |
| 1307 | return true, "" |
| 1308 | } |
| 1309 | } |
| 1310 | if action == "read" { |
| 1311 | return false, fmt.Sprintf("Cannot read %s: outside allowed read roots (%s).", path, strings.Join(roots, ", ")) |
| 1312 | } |
| 1313 | return false, fmt.Sprintf("Cannot write to %s: outside allowed roots (%s).", path, strings.Join(roots, ", ")) |
| 1314 | } |
| 1315 | |
| 1316 | func rootsFromAny(raw any) []string { |
| 1317 | switch v := raw.(type) { |