Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/2 Fixes/5861.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Disable quoting of paths sent to the debugger as arguments.
4 changes: 2 additions & 2 deletions src/client/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
'use strict';

import { traceError } from './common/logger';
import { RemoteDebuggerLauncherScriptProvider } from './debugger/debugAdapter/DebugClients/launcherProvider';
import { RemoteDebuggerExternalLauncherScriptProvider } from './debugger/debugAdapter/DebugClients/launcherProvider';

/*
* Do not introduce any breaking changes to this API.
Expand Down Expand Up @@ -42,7 +42,7 @@ export function buildApi(ready: Promise<any>) {
}),
debug: {
async getRemoteLauncherCommand(host: string, port: number, waitUntilDebuggerAttaches: boolean = true): Promise<string[]> {
return new RemoteDebuggerLauncherScriptProvider().getLauncherArgs({ host, port, waitUntilDebuggerAttaches });
return new RemoteDebuggerExternalLauncherScriptProvider().getLauncherArgs({ host, port, waitUntilDebuggerAttaches });
}
}
};
Expand Down
13 changes: 10 additions & 3 deletions src/client/debugger/debugAdapter/DebugClients/launcherProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,26 @@ export class NoDebugLauncherScriptProvider implements IDebugLauncherScriptProvid
constructor(@optional() private script: string = pathToScript) { }
public getLauncherArgs(options: LocalDebugOptions): string[] {
const customDebugger = options.customDebugger ? '--custom' : '--default';
return [this.script.fileToCommandArgument(), customDebugger, '--nodebug', '--client', '--host', options.host, '--port', options.port.toString()];
return [this.script, customDebugger, '--nodebug', '--client', '--host', options.host, '--port', options.port.toString()];
}
}

export class DebuggerLauncherScriptProvider implements IDebugLauncherScriptProvider<LocalDebugOptions> {
constructor(@optional() private script: string = pathToScript) { }
public getLauncherArgs(options: LocalDebugOptions): string[] {
const customDebugger = options.customDebugger ? '--custom' : '--default';
return [this.script.fileToCommandArgument(), customDebugger, '--client', '--host', options.host, '--port', options.port.toString()];
return [this.script, customDebugger, '--client', '--host', options.host, '--port', options.port.toString()];
}
}

export class RemoteDebuggerLauncherScriptProvider implements IRemoteDebugLauncherScriptProvider {
/**
* This class is used to provide the launch scripts so external code can launch the debugger.
* As we're passing command arguments, we need to ensure the file paths are quoted.
* @export
* @class RemoteDebuggerExternalLauncherScriptProvider
* @implements {IRemoteDebugLauncherScriptProvider}
*/
export class RemoteDebuggerExternalLauncherScriptProvider implements IRemoteDebugLauncherScriptProvider {
constructor(@optional() private script: string = pathToScript) { }
public getLauncherArgs(options: RemoteDebugOptions): string[] {
const waitArgs = options.waitUntilDebuggerAttaches ? ['--wait'] : [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { expect } from 'chai';
import * as fs from 'fs-extra';
import * as path from 'path';
import { EXTENSION_ROOT_DIR } from '../../../../client/common/constants';
import { DebuggerLauncherScriptProvider, NoDebugLauncherScriptProvider, RemoteDebuggerLauncherScriptProvider } from '../../../../client/debugger/debugAdapter/DebugClients/launcherProvider';
import { DebuggerLauncherScriptProvider, NoDebugLauncherScriptProvider, RemoteDebuggerExternalLauncherScriptProvider } from '../../../../client/debugger/debugAdapter/DebugClients/launcherProvider';

const expectedPath = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'ptvsd_launcher.py');

Expand All @@ -21,12 +21,12 @@ suite('Debugger - Launcher Script Provider', () => {
{
testName: 'When path to ptvsd launcher does not contains spaces',
path: path.join('path', 'to', 'ptvsd_launcher'),
expectedPath: 'path/to/ptvsd_launcher'
expectedPath: path.join('path', 'to', 'ptvsd_launcher')
},
{
testName: 'When path to ptvsd launcher contains spaces',
path: path.join('path', 'to', 'ptvsd_launcher', 'with spaces'),
expectedPath: '"path/to/ptvsd_launcher/with spaces"'
expectedPath: path.join('path', 'to', 'ptvsd_launcher', 'with spaces')
}
];

Expand All @@ -52,15 +52,33 @@ suite('Debugger - Launcher Script Provider', () => {
const expectedArgs = [testParams.expectedPath, '--custom', '--nodebug', '--client', '--host', 'something', '--port', '1234'];
expect(args).to.be.deep.equal(expectedArgs);
});
test('Test remote debug launcher args (and do not wait for debugger to attach)', async () => {
const args = new RemoteDebuggerLauncherScriptProvider(testParams.path).getLauncherArgs({ host: 'something', port: 1234, waitUntilDebuggerAttaches: false });
const expectedArgs = [testParams.expectedPath, '--default', '--host', 'something', '--port', '1234'];
expect(args).to.be.deep.equal(expectedArgs);
});
test('Test remote debug launcher args (and wait for debugger to attach)', async () => {
const args = new RemoteDebuggerLauncherScriptProvider(testParams.path).getLauncherArgs({ host: 'something', port: 1234, waitUntilDebuggerAttaches: true });
const expectedArgs = [testParams.expectedPath, '--default', '--host', 'something', '--port', '1234', '--wait'];
expect(args).to.be.deep.equal(expectedArgs);
});
});

suite('External Debug Launcher', () => {
[
{
testName: 'When path to ptvsd launcher does not contains spaces',
path: path.join('path', 'to', 'ptvsd_launcher'),
expectedPath: 'path/to/ptvsd_launcher'
},
{
testName: 'When path to ptvsd launcher contains spaces',
path: path.join('path', 'to', 'ptvsd_launcher', 'with spaces'),
expectedPath: '"path/to/ptvsd_launcher/with spaces"'
}
].forEach(testParams => {
suite(testParams.testName, async () => {
test('Test remote debug launcher args (and do not wait for debugger to attach)', async () => {
const args = new RemoteDebuggerExternalLauncherScriptProvider(testParams.path).getLauncherArgs({ host: 'something', port: 1234, waitUntilDebuggerAttaches: false });
const expectedArgs = [testParams.expectedPath, '--default', '--host', 'something', '--port', '1234'];
expect(args).to.be.deep.equal(expectedArgs);
});
test('Test remote debug launcher args (and wait for debugger to attach)', async () => {
const args = new RemoteDebuggerExternalLauncherScriptProvider(testParams.path).getLauncherArgs({ host: 'something', port: 1234, waitUntilDebuggerAttaches: true });
const expectedArgs = [testParams.expectedPath, '--default', '--host', 'something', '--port', '1234', '--wait'];
expect(args).to.be.deep.equal(expectedArgs);
});
});
});
});
Expand Down