From 3c0aef7a8c5057da01742ef8998e43a9fe33242a Mon Sep 17 00:00:00 2001 From: astarforbae <10215101528@stu.ecnu.edu.cn> Date: Fri, 13 Feb 2026 22:48:41 +0800 Subject: [PATCH 1/3] fix(local-replica): sanitize invalid windows chars in project folder name --- src/scm/localReplicaSCM.ts | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/scm/localReplicaSCM.ts b/src/scm/localReplicaSCM.ts index 99baafd..06d5145 100644 --- a/src/scm/localReplicaSCM.ts +++ b/src/scm/localReplicaSCM.ts @@ -70,9 +70,26 @@ export class LocalReplicaSCMProvider extends BaseSCM { super(vfs, baseUri); } + private static sanitizeProjectFolderName(projectName: string): string { + if (process.platform !== 'win32') { + return projectName; + } + let sanitized = projectName + .replace(/[<>:"/\\|?*\x00-\x1F]/g, '_') + .replace(/[. ]+$/g, ''); + if (sanitized === '') { + sanitized = 'untitled-project'; + } + if (/^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\..*)?$/i.test(sanitized)) { + sanitized = `${sanitized}_`; + } + return sanitized; + } + public static async validateBaseUri(uri: string, projectName?: string): Promise { try { let baseUri = vscode.Uri.file(uri); + const folderName = projectName===undefined ? undefined : LocalReplicaSCMProvider.sanitizeProjectFolderName(projectName); // check if the path exists try { const stat = await vscode.workspace.fs.stat(baseUri); @@ -80,8 +97,8 @@ export class LocalReplicaSCMProvider extends BaseSCM { throw new Error('Not a folder'); } // check if the project name is included in the path - if (projectName!==undefined && !baseUri.path.endsWith(`/${projectName}`)) { - baseUri = vscode.Uri.joinPath(baseUri, projectName); + if (folderName!==undefined && !baseUri.path.endsWith(`/${folderName}`)) { + baseUri = vscode.Uri.joinPath(baseUri, folderName); } } catch { // keep the baseUri as is From b885b3003681bf2ef5bccbfdf25086d1cf8d6ff9 Mon Sep 17 00:00:00 2001 From: Xingyi Zhang <133563986+astarforbae@users.noreply.github.com> Date: Fri, 13 Feb 2026 23:06:52 +0800 Subject: [PATCH 2/3] Update src/scm/localReplicaSCM.ts style(local-replica): align equality spacing in sanitizer Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/scm/localReplicaSCM.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scm/localReplicaSCM.ts b/src/scm/localReplicaSCM.ts index 06d5145..35d781c 100644 --- a/src/scm/localReplicaSCM.ts +++ b/src/scm/localReplicaSCM.ts @@ -77,7 +77,7 @@ export class LocalReplicaSCMProvider extends BaseSCM { let sanitized = projectName .replace(/[<>:"/\\|?*\x00-\x1F]/g, '_') .replace(/[. ]+$/g, ''); - if (sanitized === '') { + if (sanitized==='') { sanitized = 'untitled-project'; } if (/^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\..*)?$/i.test(sanitized)) { From 3b683cd9ab4879558c364bcd4c36fff8a365034f Mon Sep 17 00:00:00 2001 From: astarforbae <10215101528@stu.ecnu.edu.cn> Date: Mon, 23 Feb 2026 22:31:55 +0800 Subject: [PATCH 3/3] fix(local-replica): sanitize project folder names on linux and macos --- src/scm/localReplicaSCM.ts | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/scm/localReplicaSCM.ts b/src/scm/localReplicaSCM.ts index 35d781c..b0b93fc 100644 --- a/src/scm/localReplicaSCM.ts +++ b/src/scm/localReplicaSCM.ts @@ -71,18 +71,20 @@ export class LocalReplicaSCMProvider extends BaseSCM { } private static sanitizeProjectFolderName(projectName: string): string { - if (process.platform !== 'win32') { - return projectName; + let sanitized = projectName; + if (process.platform==='win32') { + sanitized = projectName + .replace(/[<>:"/\\|?*\x00-\x1F]/g, '_') + .replace(/[. ]+$/g, ''); + if (/^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\..*)?$/i.test(sanitized)) { + sanitized = `${sanitized}_`; + } + } else { + sanitized = projectName.replace(/[\/\x00]/g, '_'); } - let sanitized = projectName - .replace(/[<>:"/\\|?*\x00-\x1F]/g, '_') - .replace(/[. ]+$/g, ''); - if (sanitized==='') { + if (sanitized==='' || sanitized==='.' || sanitized==='..') { sanitized = 'untitled-project'; } - if (/^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\..*)?$/i.test(sanitized)) { - sanitized = `${sanitized}_`; - } return sanitized; }