const UNSAFE_SEGMENT = /^(\.{1,2}|\.git|git~\d+|gitmod~\d+)$|[. ]$|[\\\x00-\x1f\x7f]/i; /** Rejects names git or common filesystems treat specially (CVE-2014-9390 style `.GIT`, `git~1`, trailing dots). */ export function isUnsafeSegment(segment: string): boolean { const visible = segment.replace(/[\u200c-\u200f\u202a-\u202e\u206a-\u206f\ufeff]/g, ""); const odd = visible.toLowerCase() === ".gitmodules" && segment !== ".gitmodules"; return odd || UNSAFE_SEGMENT.test(segment) || UNSAFE_SEGMENT.test(visible); } const MAX_TREE_PATH = 4096; /** The GIT-7 path rules as a predicate, for callers that validate before a commit (the editor room). */ export function isSafeTreePath(path: string): boolean { if (path.length === 0 || path.length > MAX_TREE_PATH || path.startsWith("/") || path.endsWith("/")) return false; const segments = path.split("/"); return segments.length > 0 && segments.every((segment) => segment !== "" && !isUnsafeSegment(segment)); }