diff --git a/src/chrome/chromeDebugAdapter.ts b/src/chrome/chromeDebugAdapter.ts index 59eb4a114..42adfafed 100644 --- a/src/chrome/chromeDebugAdapter.ts +++ b/src/chrome/chromeDebugAdapter.ts @@ -281,7 +281,8 @@ export abstract class ChromeDebugAdapter implements IDebugAdapter { .then(e => { this.hookConnectionEvents(); if (this._launchAttachArgs.experimentalLibraryCode) { - this.chrome.Debugger.setBlackboxPatterns({ patterns: this._launchAttachArgs.experimentalLibraryCode }); + const patterns = this._launchAttachArgs.experimentalLibraryCode.map(glob => utils.pathGlobToBlackboxedRegex(glob)); + this.chrome.Debugger.setBlackboxPatterns({ patterns }); } return Promise.all(this.runConnection()); diff --git a/src/utils.ts b/src/utils.ts index f0ea7a9f3..885195360 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -445,8 +445,22 @@ export function pathToRegex(aPath: string): string { return aPath; } +export function pathGlobToBlackboxedRegex(glob: string): string { + return escapeRegexSpecialCharsForBlackbox(glob) + .replace(/\*\*/g, '.*') // ** -> .* + .replace(/([^\.]|^)\*/g, '$1.*') // * -> .* + + // Just to simplify + .replace(/\.\*\\\/\.\*/g, '.*') // .*\/.* -> .* + .replace(/\.\*\.\*/g, '.*'); // .*.* -> .* +} + function escapeRegexSpecialChars(str: string): string { - return str.replace(/([/\\.?*()^${}|[\]])/g, '\\$1'); + return str.replace(/([/\\.?*()^${}|[\]+])/g, '\\$1'); +} + +function escapeRegexSpecialCharsForBlackbox(str: string): string { + return str.replace(/([/\\.?()^${}|[\]+])/g, '\\$1'); } export function trimLastNewline(msg: string): string { diff --git a/test/utils.test.ts b/test/utils.test.ts index a7975b236..b9ba24d68 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -286,4 +286,30 @@ suite('Utils', () => { testPathToRegex('file:///c:\\a\\b.js', 'file:\\/\\/\\/[Cc]:\\\\a\\\\b\\.js'); }); }); + + suite('pathGlobToRegex', () => { + function testPathGlobToBlackboxedScript(glob: string, expected: string): void { + assert.equal(getUtils().pathGlobToBlackboxedRegex(glob), expected); + } + + test('universal', () => { + testPathGlobToBlackboxedScript('*', '.*'); + }); + + test('url', () => { + testPathGlobToBlackboxedScript('http://localhost:8080/node_modules/**/*.js', 'http:\\/\\/localhost:8080\\/node_modules\\/.*\\.js'); + }); + + test('path segment', () => { + testPathGlobToBlackboxedScript('node_modules', 'node_modules'); + }); + + test('file extension', () => { + testPathGlobToBlackboxedScript('*.foo.bar', '.*\\.foo\\.bar'); + }); + + test('escapes special chars except asterisk', () => { + testPathGlobToBlackboxedScript('*.+\\[(', '.*\\.\\+\\\\\\[\\('); + }); + }); });