diff --git a/package.json b/package.json index 3107e1b7..78173a08 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "iconv-lite": "^0.4.15", "moment": "2.17.1", "url-relative": "^1.0.0", + "urlencode": "^1.1.0", "vscode-debugadapter": "^1.11.0", "vscode-debugprotocol": "^1.11.0", "xmldom": "^0.1.22" diff --git a/src/custom-typings/urlencode.d.ts b/src/custom-typings/urlencode.d.ts new file mode 100644 index 00000000..de1a8de3 --- /dev/null +++ b/src/custom-typings/urlencode.d.ts @@ -0,0 +1,5 @@ + +declare module 'urlencode' { + export function decode(str: string, charset?: string): string; + export function encode(str: string, charset?: string): string; +} diff --git a/src/paths.ts b/src/paths.ts index f66238c1..a1cab3e7 100644 --- a/src/paths.ts +++ b/src/paths.ts @@ -3,6 +3,7 @@ import urlRelative = require('url-relative'); import fileUrl = require('file-url'); import * as url from 'url'; import * as path from 'path'; +import {decode} from 'urlencode'; /** converts a server-side XDebug file URI to a local path for VS Code with respect to source root settings */ export function convertDebuggerPathToClient(fileUri: string|url.Url, localSourceRoot?: string, serverSourceRoot?: string): string { @@ -10,7 +11,7 @@ export function convertDebuggerPathToClient(fileUri: string|url.Url, localSource fileUri = url.parse(fileUri); } // convert the file URI to a path - let serverPath = decodeURI(fileUri.pathname!); + let serverPath = decode(fileUri.pathname!); // strip the trailing slash from Windows paths (indicated by a drive letter with a colon) const serverIsWindows = /^\/[a-zA-Z]:\//.test(serverPath); if (serverIsWindows) { diff --git a/src/test/paths.ts b/src/test/paths.ts index 0213005e..e5c8e655 100644 --- a/src/test/paths.ts +++ b/src/test/paths.ts @@ -65,6 +65,12 @@ describe('paths', () => { (process.platform !== 'win32' ? it : it.skip)('should convert a unix URI to a unix path', () => { assert.equal(convertDebuggerPathToClient('file:///home/felix/test.php'), '/home/felix/test.php'); }); + (process.platform === 'win32' ? it : it.skip)('should handle non-unicode special characters', () => { + assert.equal( + convertDebuggerPathToClient('file:///d:/arx%20iT/2-R%C3%A9alisation/mmi/V1.0/Web/core/header.php'), + 'd:\\arx iT\\2-Réalisation\\mmi\\V1.0\\Web\\core\\header.php' + ); + }); }); describe('with source mapping', () => { (process.platform !== 'win32' ? it : it.skip)('should convert a unix URI to a unix path', () => {