Skip to content

Commit 385c4cb

Browse files
committed
fix(editor): execute oxc.path.server in win32 with shell, when its the node_module binary
1 parent f8abab2 commit 385c4cb

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

editors/vscode/client/PathValidator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
* The check for malicious characters is not needed, but it's an additional layer of security.
1010
* When using `shell: true` in `LanguageClient.ServerOptions`, it can be vulnerable to command injection.
11-
* Even though we are not using `shell: true`, it's a good practice to validate the input.
11+
* We are using `shell: true` only on Windows when the paths ends with `node_modules/.bin/oxc_language_server`.
1212
*/
1313
export function validateSafeBinaryPath(binary: string): boolean {
1414
// Check for path traversal (including Windows variants)

editors/vscode/client/extension.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,7 @@ export async function activate(context: ExtensionContext) {
137137
outputChannel,
138138
);
139139

140-
async function findBinary(): Promise<string> {
141-
let bin = configService.getUserServerBinPath();
140+
async function findBinary(bin: string | undefined): Promise<string> {
142141
if (workspace.isTrusted && bin) {
143142
try {
144143
await fsPromises.access(bin);
@@ -155,10 +154,20 @@ export async function activate(context: ExtensionContext) {
155154
);
156155
}
157156

158-
const command = await findBinary();
157+
const userDefinedBinary = configService.getUserServerBinPath();
158+
const command = await findBinary(userDefinedBinary);
159159
const run: Executable = {
160160
command: command!,
161161
options: {
162+
// On Windows we need to run the binary in a shell to be able to execute the shell npm bin script.
163+
// This is only needed when the user explicitly configures the binary to point to the npm bin script.
164+
// The extension is shipped with the `.exe` file, we don't need to run it in a shell.
165+
// Searching for the right `.exe` file inside `node_modules/` is not reliable as it depends on
166+
// the package manager used (npm, yarn, pnpm, etc) and the package version.
167+
// The npm bin script is a shell script that points to the actual binary.
168+
// Security: We validated the userDefinedBinary in `configService.getUserServerBinPath()`.
169+
shell: process.platform === 'win32' && command === userDefinedBinary &&
170+
userDefinedBinary?.endsWith('node_modules\\.bin\\oxc_language_server'),
162171
env: {
163172
...process.env,
164173
RUST_LOG: process.env.RUST_LOG || 'info',

0 commit comments

Comments
 (0)