url: modify pathToFileURL to handle extended UNC path

PR-URL: https://github.com/nodejs/node/pull/54262
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Early Riser
2024-08-12 23:48:39 +09:00
committed by GitHub
parent b8a2550ec0
commit 4dc1ae0d9b
2 changed files with 11 additions and 2 deletions

View File

@@ -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), '/'),

View File

@@ -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