perf(infra): fast path posix containment checks

This commit is contained in:
Peter Steinberger
2026-05-02 10:50:23 +01:00
parent 6cc7b759e9
commit f7b24a697d
3 changed files with 23 additions and 0 deletions

View File

@@ -74,6 +74,15 @@ describe("isPathInside", () => {
["/workspace/root", "/workspace/root/nested/file.txt", true],
["/workspace/root", "/workspace/root/..file.txt", true],
["/workspace/root", "/workspace/root/../escape.txt", false],
["/workspace/root", "/workspace/rootless/file.txt", false],
["/workspace/root", "/workspace/root/a/b/c/d/e/file.txt", true],
["/workspace/root", "/workspace/root/a/..", true],
["/workspace/root", "/workspace/root/a/../..", false],
["/workspace/root", "/workspace/root/a/b/../../../escape", false],
["/", "/anything/at/all", true],
["/", "/", true],
["foo", "foo/bar", true],
["foo", "../escape", false],
])("checks posix containment %s -> %s", (basePath, targetPath, expected) => {
expect(isPathInside(basePath, targetPath)).toBe(expected);
});

View File

@@ -4,6 +4,7 @@ import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
const NOT_FOUND_CODES = new Set(["ENOENT", "ENOTDIR"]);
const SYMLINK_OPEN_CODES = new Set(["ELOOP", "EINVAL", "ENOTSUP"]);
const PARENT_SEGMENT_PREFIX = /^\.\.(?:[\\/]|$)/u;
const POSIX_SEPARATOR_CHAR_CODE = 0x2f;
export function normalizeWindowsPathForComparison(input: string): string {
let normalized = path.win32.normalize(input);
@@ -44,6 +45,18 @@ export function isPathInside(root: string, target: string): boolean {
);
}
if (
root.length > 0 &&
root.charCodeAt(0) === POSIX_SEPARATOR_CHAR_CODE &&
target.length >= root.length &&
target.charCodeAt(0) === POSIX_SEPARATOR_CHAR_CODE &&
!target.includes("/..") &&
(target === root ||
(target.startsWith(root) && target.charCodeAt(root.length) === POSIX_SEPARATOR_CHAR_CODE))
) {
return true;
}
const resolvedRoot = path.resolve(root);
const resolvedTarget = path.resolve(target);
const relative = path.relative(resolvedRoot, resolvedTarget);