fix(core): ensure sandbox approvals are correctly persisted and matched for proactive expansions (#24577)

This commit is contained in:
Gal Zahavi
2026-04-03 14:48:18 -07:00
committed by GitHub
parent 370c45de67
commit 893ae4d29a
10 changed files with 572 additions and 104 deletions
+24 -5
View File
@@ -325,9 +325,14 @@ export function getProjectHash(projectRoot: string): string {
* - On Windows, converts to lowercase for case-insensitivity.
*/
export function normalizePath(p: string): string {
const resolved = path.resolve(p);
const platform = process.platform;
const isWindows = platform === 'win32';
const pathModule = isWindows ? path.win32 : path;
const resolved = pathModule.resolve(p);
const normalized = resolved.replace(/\\/g, '/');
return process.platform === 'win32' ? normalized.toLowerCase() : normalized;
const isCaseInsensitive = isWindows || platform === 'darwin';
return isCaseInsensitive ? normalized.toLowerCase() : normalized;
}
/**
@@ -337,11 +342,25 @@ export function normalizePath(p: string): string {
* @returns True if childPath is a subpath of parentPath, false otherwise.
*/
export function isSubpath(parentPath: string, childPath: string): boolean {
const isWindows = process.platform === 'win32';
const platform = process.platform;
const isWindows = platform === 'win32';
const isDarwin = platform === 'darwin';
const pathModule = isWindows ? path.win32 : path;
// On Windows, path.relative is case-insensitive. On POSIX, it's case-sensitive.
const relative = pathModule.relative(parentPath, childPath);
// Resolve both paths to absolute to ensure consistent comparison,
// especially when mixing relative and absolute paths or when casing differs.
let p = pathModule.resolve(parentPath);
let c = pathModule.resolve(childPath);
// On Windows, path.relative is case-insensitive.
// On POSIX (including Darwin), path.relative is case-sensitive.
// We want it to be case-insensitive on Darwin to match user expectation and sandbox policy.
if (isDarwin) {
p = p.toLowerCase();
c = c.toLowerCase();
}
const relative = pathModule.relative(p, c);
return (
!relative.startsWith(`..${pathModule.sep}`) &&