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:
@@ -97,6 +97,16 @@ void main() {
|
||||
expect(r.data['path'], 'README.md');
|
||||
});
|
||||
|
||||
test('files.read accepts an absolute path under the workspace root', () async {
|
||||
// Regression: the markdown reader publishes absolute skill paths
|
||||
// (e.g. .claude/skills/.../SKILL.md). An absolute path under root
|
||||
// must resolve, not double onto the root and 404.
|
||||
final abs = '${sandbox.absolute.path}/README.md';
|
||||
final r = await call('files.read', {'path': abs});
|
||||
expect(r.ok, isTrue);
|
||||
expect(r.data['content'], 'hi');
|
||||
});
|
||||
|
||||
test('files.read without a path returns toolError', () async {
|
||||
final r = await call('files.read', const {});
|
||||
expect(r.ok, isFalse);
|
||||
|
||||
@@ -59,6 +59,18 @@ void main() {
|
||||
}
|
||||
});
|
||||
|
||||
test('accepts an absolute path already under the root (no doubling)', () {
|
||||
// Regression: an absolute path under the root used to be joined
|
||||
// onto root (`/repo` + `/repo/x` → `/repo/repo/x`) and resolve to
|
||||
// nothing. It must normalize as-is.
|
||||
final abs = '${root.absolute.path}/.claude/skills/x/SKILL.md';
|
||||
expect(resolveUnderRoot(root, abs), abs);
|
||||
});
|
||||
|
||||
test('rejects an absolute path outside the root', () {
|
||||
expect(() => resolveUnderRoot(root, '/etc/passwd'), throwsA(isA<PathOutsideRoot>()));
|
||||
});
|
||||
|
||||
test('PathOutsideRoot.toString embeds requested + resolved + root', () {
|
||||
final e = PathOutsideRoot('r', '/abs', '/root');
|
||||
expect(e.toString(), allOf(contains('r'), contains('/abs'), contains('/root')));
|
||||
|
||||
Reference in New Issue
Block a user