src/vs/platform/terminal/common/terminalEnvironment.ts

128 LOC · 122 covered · 6 uncovered · 31 ranges · 73 concepts · 18 introducers · 57 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- terminalEnvironment.ts ×4
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { OperatingSystem, OS } from '../../../base/common/platform.js';
7 > import { IShellLaunchConfig, TerminalShellType, PosixShellType, WindowsShellType, GeneralShellType } from './terminal.js';
8 >
9 > /**
10 > * Aggressively escape non-windows paths to prepare for being sent to a shell. This will do some
11 > * escaping inaccurately to be careful about possible script injection via the file path. For
12 > * example, we're trying to prevent this sort of attack: `/foo/file$(echo evil)`.
13 > */
14 > export function escapeNonWindowsPath(path: string, shellType?: TerminalShellType): string {
15 > let newPath = path; terminalEnvironment.ts ×8
16 > if (newPath.includes('\\')) {
17 newPath = newPath.replace(/\\/g, '\\\\');
18 }
20 > // Define shell-specific escaping rules
21 > interface ShellEscapeConfig {
22 > // How to handle paths with both single and double quotes
23 > bothQuotes: (path: string) => string;
24 > // How to handle paths with only single quotes
25 > singleQuotes: (path: string) => string;
26 > // How to handle paths with no single quotes (may have double quotes)
27 > noSingleQuotes: (path: string) => string;
28 > }
29 >
30 > let escapeConfig: ShellEscapeConfig;
31 > switch (shellType) {
32 > case PosixShellType.Bash:
33 > case PosixShellType.Sh:
34 > case PosixShellType.Zsh:
35 > case WindowsShellType.GitBash:
36 > escapeConfig = { terminalEnvironment.ts ×1
37 > bothQuotes: (path) => `$'${path.replace(/'/g, '\\\'')}'`,
38 > singleQuotes: (path) => `'${path.replace(/'/g, '\\\'')}'`,
39 > noSingleQuotes: (path) => `'${path}'`
40 > };
41 > break;
42 > case PosixShellType.Fish: terminalEnvironment.ts ×8
43 > escapeConfig = { terminalEnvironment.ts ×1
44 > bothQuotes: (path) => `"${path.replace(/"/g, '\\"')}"`,
45 > singleQuotes: (path) => `'${path.replace(/'/g, '\\\'')}'`,
46 > noSingleQuotes: (path) => `'${path}'`
47 > };
48 > break;
49 > case GeneralShellType.PowerShell: terminalEnvironment.ts ×8
50 > // PowerShell should be handled separately in preparePathForShell terminalEnvironment.ts ×1
51 > // but if we get here, use PowerShell escaping
52 > escapeConfig = {
53 > bothQuotes: (path) => `"${path.replace(/"/g, '`"')}"`,
54 > singleQuotes: (path) => `'${path.replace(/'/g, '\'\'')}'`,
55 > noSingleQuotes: (path) => `'${path}'`
56 > };
57 > break;
59 > // Default to POSIX shell escaping for unknown shells terminalEnvironment.ts ×1
60 > escapeConfig = {
61 > bothQuotes: (path) => `$'${path.replace(/'/g, '\\\'')}'`,
62 > singleQuotes: (path) => `'${path.replace(/'/g, '\\\'')}'`,
63 > noSingleQuotes: (path) => `'${path}'`
64 > };
65 > break;
67 >
68 > // Remove dangerous characters except single and double quotes, which we'll escape properly
69 > const bannedChars = /[\`\$\|\&\>\~\#\!\^\*\;\<]/g;
70 > newPath = newPath.replace(bannedChars, '');
71 >
72 > // Apply shell-specific escaping based on quote content
73 > if (newPath.includes('\'') && newPath.includes('"')) {
74 > return escapeConfig.bothQuotes(newPath); terminalEnvironment.ts ×1
75 > } else if (newPath.includes('\'')) { terminalEnvironment.ts ×8
76 > return escapeConfig.singleQuotes(newPath); terminalEnvironment.ts ×1
78 > return escapeConfig.noSingleQuotes(newPath);
79 > }
80 > }
82 > /**
83 > * Collapses the user's home directory into `~` if it exists within the path, this gives a shorter
84 > * path that is more suitable within the context of a terminal.
85 > */
86 > export function collapseTildePath(path: string | undefined, userHome: string | undefined, separator: string): string {
87 > if (!path) { terminalEnvironment.ts ×1
88 > return ''; terminalEnvironment.ts ×1
89 > }
90 > if (!userHome) { terminalEnvironment.ts ×1
91 > return path; terminalEnvironment.ts ×1
92 > }
93 > // Trim the trailing separator from the end if it exists terminalEnvironment.ts ×2
94 > if (userHome.match(/[\/\\]$/)) {
95 > userHome = userHome.slice(0, userHome.length - 1); terminalEnvironment.ts ×1
96 > }
97 > const normalizedPath = path.replace(/\\/g, '/').toLowerCase(); terminalEnvironment.ts ×2
98 > const normalizedUserHome = userHome.replace(/\\/g, '/').toLowerCase();
99 > if (!normalizedPath.includes(normalizedUserHome)) {
100 > return path; terminalEnvironment.ts ×1
101 > }
102 > return `~${separator}${path.slice(userHome.length + 1)}`; terminalEnvironment.ts ×1
103 > }
105 > /**
106 > * Sanitizes a cwd string, removing any wrapping quotes and making the Windows drive letter
107 > * uppercase.
108 > * @param cwd The directory to sanitize.
109 > */
110 > export function sanitizeCwd(cwd: string): string {
111 > // Sanity check that the cwd is not wrapped in quotes (see #160109) terminalEnvironment.ts ×3
112 > if (cwd.match(/^['"].*['"]$/)) {
113 > cwd = cwd.substring(1, cwd.length - 1); terminalEnvironment.ts ×1
114 > }
115 > // Make the drive letter uppercase on Windows (see #9448) terminalEnvironment.ts ×3
116 > if (OS === OperatingSystem.Windows && cwd && cwd[1] === ':') {
117 return cwd[0].toUpperCase() + cwd.substring(1);
118 }
119 > return cwd; terminalEnvironment.ts ×3
120 > }
122 > /**
123 > * Determines whether the given shell launch config should use the environment variable collection.
124 > * @param slc The shell launch config to check.
125 > */
126 > export function shouldUseEnvironmentVariableCollection(slc: IShellLaunchConfig): boolean {
127 return !slc.strictEnv;
128 }