Merge pull request #162984 from microsoft/tyriar/162456

Sanitize shell integration cwd early
This commit is contained in:
Daniel Imms 2022-10-07 14:28:55 -07:00 committed by GitHub
commit 7f4ac698ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 16 deletions

View file

@ -3,6 +3,8 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { OperatingSystem, OS } from 'vs/base/common/platform';
export function escapeNonWindowsPath(path: string): string {
let newPath = path;
if (newPath.indexOf('\\') !== 0) {
@ -35,3 +37,20 @@ export function collapseTildePath(path: string | undefined, userHome: string | u
}
return `~${separator}${path.slice(userHome.length + 1)}`;
}
/**
* Sanitizes a cwd string, removing any wrapping quotes and making the Windows drive letter
* uppercase.
* @param cwd The directory to sanitize.
*/
export function sanitizeCwd(cwd: string): string {
// Sanity check that the cwd is not wrapped in quotes (see #160109)
if (cwd.match(/^['"].*['"]$/)) {
cwd = cwd.substring(1, cwd.length - 1);
}
// Make the drive letter uppercase on Windows (see #9448)
if (OS === OperatingSystem.Windows && cwd && cwd[1] === ':') {
return cwd[0].toUpperCase() + cwd.substring(1);
}
return cwd;
}

View file

@ -20,6 +20,7 @@ import { BufferMarkCapability } from 'vs/platform/terminal/common/capabilities/b
// eslint-disable-next-line local/code-import-patterns
import type { ITerminalAddon, Terminal } from 'xterm-headless';
import { URI } from 'vs/base/common/uri';
import { sanitizeCwd } from 'vs/platform/terminal/common/terminalEnvironment';
/**
@ -383,6 +384,7 @@ export class ShellIntegrationAddon extends Disposable implements IShellIntegrati
}
private _updateCwd(value: string) {
value = sanitizeCwd(value);
this._createOrGetCwdDetection().updateCwd(value);
const commandDetection = this.capabilities.get(TerminalCapability.CommandDetection);
commandDetection?.setCwd(value);

View file

@ -4,7 +4,8 @@
*--------------------------------------------------------------------------------------------*/
import { strictEqual } from 'assert';
import { collapseTildePath } from 'vs/platform/terminal/common/terminalEnvironment';
import { OperatingSystem, OS } from 'vs/base/common/platform';
import { collapseTildePath, sanitizeCwd } from 'vs/platform/terminal/common/terminalEnvironment';
suite('terminalEnvironment', () => {
suite('collapseTildePath', () => {
@ -37,4 +38,15 @@ suite('terminalEnvironment', () => {
strictEqual(collapseTildePath('/foo/bar/baz', '/foo/', '/'), '~/bar/baz');
});
});
suite('sanitizeCwd', () => {
if (OS === OperatingSystem.Windows) {
test('should make the Windows drive letter uppercase', () => {
strictEqual(sanitizeCwd('c:\\foo\\bar'), 'C:\\foo\\bar');
});
}
test('should remove any wrapping quotes', () => {
strictEqual(sanitizeCwd('\'/foo/bar\''), '/foo/bar');
strictEqual(sanitizeCwd('"/foo/bar"'), '/foo/bar');
});
});
});

View file

@ -14,7 +14,8 @@ import { IConfigurationResolverService } from 'vs/workbench/services/configurati
import { sanitizeProcessEnvironment } from 'vs/base/common/processes';
import { ILogService } from 'vs/platform/log/common/log';
import { IShellLaunchConfig, ITerminalEnvironment, TerminalSettingId, TerminalSettingPrefix } from 'vs/platform/terminal/common/terminal';
import { IProcessEnvironment, isWindows, locale, OperatingSystem, OS, platform, Platform } from 'vs/base/common/platform';
import { IProcessEnvironment, isWindows, locale, platform, Platform } from 'vs/base/common/platform';
import { sanitizeCwd } from 'vs/platform/terminal/common/terminalEnvironment';
export function mergeEnvironments(parent: IProcessEnvironment, other: ITerminalEnvironment | undefined): void {
if (!other) {
@ -190,7 +191,7 @@ export async function getCwd(
if (shell.cwd) {
const unresolved = (typeof shell.cwd === 'object') ? shell.cwd.fsPath : shell.cwd;
const resolved = await _resolveCwd(unresolved, variableResolver);
return _sanitizeCwd(resolved || unresolved);
return sanitizeCwd(resolved || unresolved);
}
let cwd: string | undefined;
@ -213,7 +214,7 @@ export async function getCwd(
cwd = root ? root.fsPath : userHome || '';
}
return _sanitizeCwd(cwd);
return sanitizeCwd(cwd);
}
async function _resolveCwd(cwd: string, variableResolver: VariableResolver | undefined, logService?: ILogService): Promise<string | undefined> {
@ -228,18 +229,6 @@ async function _resolveCwd(cwd: string, variableResolver: VariableResolver | und
return cwd;
}
function _sanitizeCwd(cwd: string): string {
// Sanity check that the cwd is not wrapped in quotes (see #160109)
if (cwd.match(/$['"].*['"]^/)) {
cwd = cwd.substring(1, cwd.length - 1);
}
// Make the drive letter uppercase on Windows (see #9448)
if (OS === OperatingSystem.Windows && cwd && cwd[1] === ':') {
return cwd[0].toUpperCase() + cwd.substr(1);
}
return cwd;
}
export type TerminalShellSetting = (
TerminalSettingId.AutomationShellWindows
| TerminalSettingId.AutomationShellMacOs