mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-19 13:33:35 +08:00
Windows folder selection can surface drive roots as D:, which Node treats as drive-relative instead of the absolute D:\ root. Normalize drive-root inputs before resolving launch directories, filesystem access roots, transcript metadata, and workspace paths. Use path.relative containment checks so drive roots and child projects remain distinct in session grouping and file access. Constraint: Windows drive-root inputs may arrive as C:, D:, or any other single-letter drive prefix Rejected: Special-case only D: | every Windows drive letter has the same drive-relative semantics Confidence: high Scope-risk: moderate Directive: Keep Windows drive-root normalization centralized; do not reintroduce string-prefix containment checks for workspace roots Tested: bun test src/server/__tests__/windows-drive-path.test.ts src/server/__tests__/filesystem.test.ts src/server/__tests__/sessions.test.ts src/server/__tests__/workspace-service.test.ts Tested: cd desktop && bun run test -- --run src/components/layout/Sidebar.test.tsx Tested: bun run check:server Tested: cd desktop && bun run lint Not-tested: Real Windows desktop smoke on a physical Windows machine Related: #601
31 lines
994 B
TypeScript
31 lines
994 B
TypeScript
import * as path from 'node:path'
|
|
|
|
export function normalizeDriveRootPathForPlatform(
|
|
filePath: string,
|
|
platform: NodeJS.Platform = process.platform,
|
|
): string {
|
|
if (platform !== 'win32') return filePath
|
|
|
|
const driveRootMatch = filePath.match(/^([a-zA-Z]):$/)
|
|
if (!driveRootMatch) return filePath
|
|
|
|
return `${driveRootMatch[1]}:\\`
|
|
}
|
|
|
|
export function isSameOrInsidePathForPlatform(
|
|
targetPath: string,
|
|
rootPath: string,
|
|
platform: NodeJS.Platform = process.platform,
|
|
): boolean {
|
|
const pathApi = platform === 'win32' ? path.win32 : path
|
|
const normalize = (filePath: string) => {
|
|
const resolved = pathApi.resolve(normalizeDriveRootPathForPlatform(filePath, platform))
|
|
return platform === 'win32' ? resolved.toLowerCase() : resolved
|
|
}
|
|
const target = normalize(targetPath)
|
|
const root = normalize(rootPath)
|
|
const relative = pathApi.relative(root, target)
|
|
|
|
return relative === '' || (!!relative && !relative.startsWith('..') && !pathApi.isAbsolute(relative))
|
|
}
|