blob: 167b3f024ac36807b7d209018b32bac2973c1716 [file]
import { strict as assert } from 'node:assert';
import { win32, posix } from 'node:path';
import { describe, test } from 'node:test';
import { isPathInside } from '../path-containment.js';
describe('isPathInside', () => {
test('rejects cross-drive Windows targets (different drive is not inside root)', () => {
// path.win32.relative returns the target unchanged (absolute) when root
// and target are on different drives; this is the escape vector the helper
// must close before the `..` check.
assert.equal(isPathInside('C:\\repo', 'D:\\secret', win32), false);
});
test('rejects same-drive Windows targets outside root', () => {
assert.equal(isPathInside('C:\\repo', 'C:\\other\\secret', win32), false);
});
test('allows same-drive Windows targets under root', () => {
assert.equal(isPathInside('C:\\repo', 'C:\\repo\\sub', win32), true);
assert.equal(isPathInside('C:\\repo', 'C:\\repo', win32), true);
});
test('rejects parent-directory escape on POSIX', () => {
assert.equal(isPathInside('/repo', '/etc/passwd', posix), false);
});
test('allows POSIX targets under root', () => {
assert.equal(isPathInside('/repo', '/repo/sub', posix), true);
assert.equal(isPathInside('/repo', '/repo', posix), true);
});
test('allows paths whose first segment starts with ".." but is not a parent reference (e.g. ..rules)', () => {
assert.equal(isPathInside('/repo', '/repo/..rules/AGENTS.md', posix), true);
assert.equal(isPathInside('C:\\repo', 'C:\\repo\\..rules\\AGENTS.md', win32), true);
});
});