mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 14:04:58 +00:00
fix(agents): normalize windows workspace path boundary checks (#30766)
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
@@ -8,15 +8,51 @@ type RelativePathOptions = {
|
||||
includeRootInError?: boolean;
|
||||
};
|
||||
|
||||
function normalizeWindowsPathForComparison(input: string): string {
|
||||
let normalized = path.win32.normalize(input);
|
||||
if (normalized.startsWith("\\\\?\\")) {
|
||||
normalized = normalized.slice(4);
|
||||
if (normalized.toUpperCase().startsWith("UNC\\")) {
|
||||
normalized = `\\\\${normalized.slice(4)}`;
|
||||
}
|
||||
}
|
||||
return normalized.replaceAll("/", "\\").toLowerCase();
|
||||
}
|
||||
|
||||
function toRelativePathUnderRoot(params: {
|
||||
root: string;
|
||||
candidate: string;
|
||||
options?: RelativePathOptions;
|
||||
}): string {
|
||||
const rootResolved = path.resolve(params.root);
|
||||
const resolvedCandidate = path.resolve(
|
||||
resolveSandboxInputPath(params.candidate, params.options?.cwd ?? params.root),
|
||||
const resolvedInput = resolveSandboxInputPath(
|
||||
params.candidate,
|
||||
params.options?.cwd ?? params.root,
|
||||
);
|
||||
|
||||
if (process.platform === "win32") {
|
||||
const rootResolved = path.win32.resolve(params.root);
|
||||
const resolvedCandidate = path.win32.resolve(resolvedInput);
|
||||
const rootForCompare = normalizeWindowsPathForComparison(rootResolved);
|
||||
const targetForCompare = normalizeWindowsPathForComparison(resolvedCandidate);
|
||||
const relative = path.win32.relative(rootForCompare, targetForCompare);
|
||||
if (relative === "" || relative === ".") {
|
||||
if (params.options?.allowRoot) {
|
||||
return "";
|
||||
}
|
||||
const boundary = params.options?.boundaryLabel ?? "workspace root";
|
||||
const suffix = params.options?.includeRootInError ? ` (${rootResolved})` : "";
|
||||
throw new Error(`Path escapes ${boundary}${suffix}: ${params.candidate}`);
|
||||
}
|
||||
if (relative.startsWith("..") || path.win32.isAbsolute(relative)) {
|
||||
const boundary = params.options?.boundaryLabel ?? "workspace root";
|
||||
const suffix = params.options?.includeRootInError ? ` (${rootResolved})` : "";
|
||||
throw new Error(`Path escapes ${boundary}${suffix}: ${params.candidate}`);
|
||||
}
|
||||
return relative;
|
||||
}
|
||||
|
||||
const rootResolved = path.resolve(params.root);
|
||||
const resolvedCandidate = path.resolve(resolvedInput);
|
||||
const relative = path.relative(rootResolved, resolvedCandidate);
|
||||
if (relative === "" || relative === ".") {
|
||||
if (params.options?.allowRoot) {
|
||||
|
||||
Reference in New Issue
Block a user