fix markdown reader 404 on absolute paths

resolveUnderRoot joined an absolute input onto the workspace root
(/repo + /repo/x → /repo/repo/x), so files.read 404'd on a file that
exists. The Claude Config tab hands the reader a skill's absolute
SKILL.md path, which hit this. Normalize an absolute input as-is; the
existing containment check still rejects absolute paths outside the
root, so the T-102 boundary is preserved.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-01 08:50:00 +02:00
co-authored by Claude Opus 4.8
parent 4aed6c12a5
commit ade8a88b75
8 changed files with 52 additions and 1 deletions
+6 -1
View File
@@ -26,7 +26,12 @@ class PathOutsideRoot implements Exception {
/// without touching disk (T-102).
String resolveUnderRoot(Directory root, String relative) {
final rootPath = _normalize(root.absolute.path);
final joined = _normalize('$rootPath${Platform.pathSeparator}$relative');
// An absolute input is normalized as-is rather than joined onto the
// root — otherwise a path already under the root gets doubled
// (`/repo` + `/repo/x` → `/repo/repo/x`) and resolves to nothing.
// Containment is still enforced below, so an absolute path *outside*
// the root is rejected exactly as a `..` traversal is.
final joined = relative.startsWith(Platform.pathSeparator) ? _normalize(relative) : _normalize('$rootPath${Platform.pathSeparator}$relative');
// Containment check: joined must equal rootPath, or start with
// rootPath + separator. Equality covers `relative == ''` (the