From 68f519f48eee07da0d5667f1811e17a145c17f5e Mon Sep 17 00:00:00 2001 From: EarlyRiser42 Date: Wed, 7 Aug 2024 21:48:09 -0400 Subject: [PATCH] url: modify pathToFileURL to handle extended UNC path --- lib/internal/url.js | 9 +++++++-- test/parallel/test-url-pathtofileurl.js | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/internal/url.js b/lib/internal/url.js index fead9b2dbdbba6..3cb186182947a1 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -1540,7 +1540,12 @@ function pathToFileURL(filepath, options = kEmptyObject) { if ((windows ?? isWindows) && StringPrototypeStartsWith(filepath, '\\\\')) { const outURL = new URL('file://'); // UNC path format: \\server\share\resource - const hostnameEndIndex = StringPrototypeIndexOf(filepath, '\\', 2); + // Handle extended UNC path and standard UNC path + // "\\?\UNC\" path prefix should be ignored. + // Ref: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation + const isExtendedUNC = StringPrototypeStartsWith(filepath, '\\\\?\\UNC\\'); + const prefixLength = isExtendedUNC ? 8 : 2; + const hostnameEndIndex = StringPrototypeIndexOf(filepath, '\\', prefixLength); if (hostnameEndIndex === -1) { throw new ERR_INVALID_ARG_VALUE( 'path', @@ -1555,7 +1560,7 @@ function pathToFileURL(filepath, options = kEmptyObject) { 'Empty UNC servername', ); } - const hostname = StringPrototypeSlice(filepath, 2, hostnameEndIndex); + const hostname = StringPrototypeSlice(filepath, prefixLength, hostnameEndIndex); outURL.hostname = domainToASCII(hostname); outURL.pathname = encodePathChars( RegExpPrototypeSymbolReplace(backslashRegEx, StringPrototypeSlice(filepath, hostnameEndIndex), '/'), diff --git a/test/parallel/test-url-pathtofileurl.js b/test/parallel/test-url-pathtofileurl.js index abbd6c95cb53dc..20609eb0ff5c9f 100644 --- a/test/parallel/test-url-pathtofileurl.js +++ b/test/parallel/test-url-pathtofileurl.js @@ -104,8 +104,12 @@ const windowsTestCases = [ { path: 'C:\\€', expected: 'file:///C:/%E2%82%AC' }, // Rocket emoji (non-BMP code point) { path: 'C:\\🚀', expected: 'file:///C:/%F0%9F%9A%80' }, + // Local extended path + { path: '\\\\?\\C:\\path\\to\\file.txt', expected: 'file:///C:/path/to/file.txt' }, // UNC path (see https://docs.microsoft.com/en-us/archive/blogs/ie/file-uris-in-windows) { path: '\\\\nas\\My Docs\\File.doc', expected: 'file://nas/My%20Docs/File.doc' }, + // Extended UNC path + { path: '\\\\?\\UNC\\server\\share\\folder\\file.txt', expected: 'file://server/share/folder/file.txt' }, ]; const posixTestCases = [ // Lowercase ascii alpha