diff --git a/lib/internal/url.js b/lib/internal/url.js index 3cb186182947a1..702caf8788ddb3 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -1518,11 +1518,20 @@ const carriageReturnRegEx = /\r/g; const tabRegEx = /\t/g; const questionRegex = /\?/g; const hashRegex = /#/g; +const leftBracketRegEx = /\[/g; +const rightBracketRegEx = /\]/g; +const caretRegEx = /\^/g; function encodePathChars(filepath, options = kEmptyObject) { const windows = options?.windows; if (StringPrototypeIndexOf(filepath, '%') !== -1) filepath = RegExpPrototypeSymbolReplace(percentRegEx, filepath, '%25'); + if (StringPrototypeIndexOf(filepath, '[') !== -1) + filepath = RegExpPrototypeSymbolReplace(leftBracketRegEx, filepath, '%5B'); + if (StringPrototypeIndexOf(filepath, ']') !== -1) + filepath = RegExpPrototypeSymbolReplace(rightBracketRegEx, filepath, '%5D'); + if (StringPrototypeIndexOf(filepath, '^') !== -1) + filepath = RegExpPrototypeSymbolReplace(caretRegEx, filepath, '%5E'); // In posix, backslash is a valid character in paths: if (!(windows ?? isWindows) && StringPrototypeIndexOf(filepath, '\\') !== -1) filepath = RegExpPrototypeSymbolReplace(backslashRegEx, filepath, '%5C'); diff --git a/test/parallel/test-url-pathtofileurl.js b/test/parallel/test-url-pathtofileurl.js index 20609eb0ff5c9f..9e3d0497194dfe 100644 --- a/test/parallel/test-url-pathtofileurl.js +++ b/test/parallel/test-url-pathtofileurl.js @@ -88,6 +88,12 @@ const windowsTestCases = [ { path: 'C:\\foo;bar', expected: 'file:///C:/foo;bar' }, // percent { path: 'C:\\foo%bar', expected: 'file:///C:/foo%25bar' }, + // caret + { path: 'C:\\foo^bar', expected: 'file:///C:/foo%5Ebar' }, + // left bracket + { path: 'C:\\foo[bar', expected: 'file:///C:/foo%5Bbar' }, + // right bracket + { path: 'C:\\foo]bar', expected: 'file:///C:/foo%5Dbar' }, // backslash { path: 'C:\\foo\\bar', expected: 'file:///C:/foo/bar' }, // backspace @@ -138,6 +144,12 @@ const posixTestCases = [ { path: '/foo;bar', expected: 'file:///foo;bar' }, // percent { path: '/foo%bar', expected: 'file:///foo%25bar' }, + // caret + { path: '/foo^bar', expected: 'file:///foo%5Ebar' }, + // left bracket + { path: '/foo[bar', expected: 'file:///foo%5Bbar' }, + // right bracket + { path: '/foo]bar', expected: 'file:///foo%5Dbar' }, // backslash { path: '/foo\\bar', expected: 'file:///foo%5Cbar' }, // backspace