Skip to content

Commit b57b987

Browse files
authored
Re-use isValidBasename in file picker (microsoft#73332)
Fixes microsoft#72866
1 parent 0c9dd09 commit b57b987

2 files changed

Lines changed: 13 additions & 45 deletions

File tree

src/vs/base/common/extpath.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -139,36 +139,39 @@ export function isUNC(path: string): boolean {
139139
}
140140

141141
// Reference: https://en.wikipedia.org/wiki/Filename
142-
const INVALID_FILE_CHARS = isWindows ? /[\\/:\*\?"<>\|]/g : /[\\/]/g;
142+
const WINDOWS_INVALID_FILE_CHARS = /[\\/:\*\?"<>\|]/g;
143+
const UNIX_INVALID_FILE_CHARS = /[\\/]/g;
143144
const WINDOWS_FORBIDDEN_NAMES = /^(con|prn|aux|clock\$|nul|lpt[0-9]|com[0-9])$/i;
144-
export function isValidBasename(name: string | null | undefined): boolean {
145+
export function isValidBasename(name: string | null | undefined, isWindowsOS: boolean = isWindows): boolean {
146+
const invalidFileChars = isWindowsOS ? WINDOWS_INVALID_FILE_CHARS : UNIX_INVALID_FILE_CHARS;
147+
145148
if (!name || name.length === 0 || /^\s+$/.test(name)) {
146149
return false; // require a name that is not just whitespace
147150
}
148151

149-
INVALID_FILE_CHARS.lastIndex = 0; // the holy grail of software development
150-
if (INVALID_FILE_CHARS.test(name)) {
152+
invalidFileChars.lastIndex = 0; // the holy grail of software development
153+
if (invalidFileChars.test(name)) {
151154
return false; // check for certain invalid file characters
152155
}
153156

154-
if (isWindows && WINDOWS_FORBIDDEN_NAMES.test(name)) {
157+
if (isWindowsOS && WINDOWS_FORBIDDEN_NAMES.test(name)) {
155158
return false; // check for certain invalid file names
156159
}
157160

158161
if (name === '.' || name === '..') {
159162
return false; // check for reserved values
160163
}
161164

162-
if (isWindows && name[name.length - 1] === '.') {
165+
if (isWindowsOS && name[name.length - 1] === '.') {
163166
return false; // Windows: file cannot end with a "."
164167
}
165168

166-
if (isWindows && name.length !== name.trim().length) {
169+
if (isWindowsOS && name.length !== name.trim().length) {
167170
return false; // Windows: file cannot end with a whitespace
168171
}
169172

170173
if (name.length > 255) {
171-
return false; // most file systems do not allow files > 255 lenth
174+
return false; // most file systems do not allow files > 255 length
172175
}
173176

174177
return true;

src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { equalsIgnoreCase, format, startsWithIgnoreCase } from 'vs/base/common/s
2626
import { OpenLocalFileAction, OpenLocalFileFolderAction, OpenLocalFolderAction } from 'vs/workbench/browser/actions/workspaceActions';
2727
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
2828
import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment';
29+
import { isValidBasename } from 'vs/base/common/extpath';
2930
import { RemoteFileDialogContext } from 'vs/workbench/browser/contextkeys';
3031

3132
interface FileQuickPickItem extends IQuickPickItem {
@@ -40,11 +41,6 @@ enum UpdateResult {
4041
InvalidPath
4142
}
4243

43-
// Reference: https://en.wikipedia.org/wiki/Filename
44-
const WINDOWS_INVALID_FILE_CHARS = /[\\/:\*\?"<>\|]/g;
45-
const UNIX_INVALID_FILE_CHARS = /[\\/]/g;
46-
const WINDOWS_FORBIDDEN_NAMES = /^(con|prn|aux|clock\$|nul|lpt[0-9]|com[0-9])$/i;
47-
4844
export class RemoteFileDialog {
4945
private options: IOpenDialogOptions;
5046
private currentFolder: URI;
@@ -618,7 +614,7 @@ export class RemoteFileDialog {
618614
// Show a yes/no prompt
619615
const message = nls.localize('remoteFileDialog.validateExisting', '{0} already exists. Are you sure you want to overwrite it?', resources.basename(uri));
620616
return this.yesNoPrompt(uri, message);
621-
} else if (!(await this.isValidBaseName(resources.basename(uri)))) {
617+
} else if (!(isValidBasename(resources.basename(uri), await this.isWindowsOS()))) {
622618
// Filename not allowed
623619
this.filePickBox.validationMessage = nls.localize('remoteFileDialog.validateBadFilename', 'Please enter a valid file name.');
624620
return Promise.resolve(false);
@@ -712,37 +708,6 @@ export class RemoteFileDialog {
712708
return isWindowsOS;
713709
}
714710

715-
private async isValidBaseName(name: string): Promise<boolean> {
716-
if (!name || name.length === 0 || /^\s+$/.test(name)) {
717-
return false; // require a name that is not just whitespace
718-
}
719-
720-
const isWindowsOS = await this.isWindowsOS();
721-
const INVALID_FILE_CHARS = isWindowsOS ? WINDOWS_INVALID_FILE_CHARS : UNIX_INVALID_FILE_CHARS;
722-
INVALID_FILE_CHARS.lastIndex = 0; // the holy grail of software development
723-
if (INVALID_FILE_CHARS.test(name)) {
724-
return false; // check for certain invalid file characters
725-
}
726-
727-
if (isWindowsOS && WINDOWS_FORBIDDEN_NAMES.test(name)) {
728-
return false; // check for certain invalid file names
729-
}
730-
731-
if (name === '.' || name === '..') {
732-
return false; // check for reserved values
733-
}
734-
735-
if (isWindowsOS && name[name.length - 1] === '.') {
736-
return false; // Windows: file cannot end with a "."
737-
}
738-
739-
if (isWindowsOS && name.length !== name.trim().length) {
740-
return false; // Windows: file cannot end with a whitespace
741-
}
742-
743-
return true;
744-
}
745-
746711
private endsWithSlash(s: string) {
747712
return /[\/\\]$/.test(s);
748713
}

0 commit comments

Comments
 (0)