diff --git a/src/test/suite/pathUtil.test.ts b/src/test/suite/pathUtil.test.ts index dad4fcfc..c6b64713 100644 --- a/src/test/suite/pathUtil.test.ts +++ b/src/test/suite/pathUtil.test.ts @@ -122,6 +122,24 @@ describe('GetWorkspaceFromRelativePath / GetWorkspaceFromAbsolutePath', () => { }); }); +describe('EscapePathParts / UnescapePathParts', () => { + it('escapes # in a path segment so it is not treated as a URL fragment delimiter', () => { + const actual = PathUtil.EscapePathParts('my#folder/index.html'); + assert.strictEqual(actual, 'my%23folder/index.html'); + }); + + it('round-trips a path segment containing #', () => { + const escaped = PathUtil.EscapePathParts('my#folder/index.html'); + const actual = PathUtil.UnescapePathParts(escaped); + assert.strictEqual(actual, 'my#folder/index.html'); + }); + + it('escapes a leading # the same as one in the middle of a segment', () => { + const actual = PathUtil.EscapePathParts('#folder/index.html'); + assert.strictEqual(actual, '%23folder/index.html'); + }); +}); + describe('getEndpointParent', () => { it('returns the correct endpoint parent for full paths', async () => { const endpoint1 = PathUtil.GetEndpointParent('c:/Users/TestUser/workspace1/'); diff --git a/src/utils/pathUtil.ts b/src/utils/pathUtil.ts index 5f01fdd9..c08be01a 100644 --- a/src/utils/pathUtil.ts +++ b/src/utils/pathUtil.ts @@ -26,7 +26,7 @@ export class PathUtil { const newParts = parts .filter((part) => part.length > 0) - .map((filterdPart) => encodeURI(filterdPart)); + .map((filterdPart) => encodeURIComponent(filterdPart)); return newParts.join('/'); } @@ -39,7 +39,7 @@ export class PathUtil { const parts = file.split('/'); const newParts = parts .filter((part) => part.length > 0) - .map((filterdPart) => decodeURI(filterdPart)); + .map((filterdPart) => decodeURIComponent(filterdPart)); return newParts.join('/'); }