| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 9a79020 commit 1a9496a
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -27,6 +27,7 @@ const { getConstructorOf, removeColors } = require('internal/util'); | |||
| 27 | 27 | const { | |
| 28 | 28 | ERR_ARG_NOT_ITERABLE, | |
| 29 | 29 | ERR_INVALID_ARG_TYPE, | |
| 30 | + ERR_INVALID_ARG_VALUE, | ||
| 30 | 31 | ERR_INVALID_CALLBACK, | |
| 31 | 32 | ERR_INVALID_FILE_URL_HOST, | |
| 32 | 33 | ERR_INVALID_FILE_URL_PATH, | |
@@ -1366,27 +1367,54 @@ const backslashRegEx = /\\/g; | |||
| 1366 | 1367 | const newlineRegEx = /\n/g; | |
| 1367 | 1368 | const carriageReturnRegEx = /\r/g; | |
| 1368 | 1369 | const tabRegEx = /\t/g; | |
| 1370 | + | ||
| 1371 | + function encodePathChars(filepath) { | ||
| 1372 | + if (filepath.includes('%')) | ||
| 1373 | + filepath = filepath.replace(percentRegEx, '%25'); | ||
| 1374 | + // In posix, backslash is a valid character in paths: | ||
| 1375 | + if (!isWindows && filepath.includes('\\')) | ||
| 1376 | + filepath = filepath.replace(backslashRegEx, '%5C'); | ||
| 1377 | + if (filepath.includes('\n')) | ||
| 1378 | + filepath = filepath.replace(newlineRegEx, '%0A'); | ||
| 1379 | + if (filepath.includes('\r')) | ||
| 1380 | + filepath = filepath.replace(carriageReturnRegEx, '%0D'); | ||
| 1381 | + if (filepath.includes('\t')) | ||
| 1382 | + filepath = filepath.replace(tabRegEx, '%09'); | ||
| 1383 | + return filepath; | ||
| 1384 | + } | ||
| 1385 | + | ||
| 1369 | 1386 | function pathToFileURL(filepath) { | |
| 1370 | - let resolved = path.resolve(filepath); | ||
| 1371 | - // path.resolve strips trailing slashes so we must add them back | ||
| 1372 | - const filePathLast = filepath.charCodeAt(filepath.length - 1); | ||
| 1373 | - if ((filePathLast === CHAR_FORWARD_SLASH || | ||
| 1374 | - (isWindows && filePathLast === CHAR_BACKWARD_SLASH)) && | ||
| 1375 | - resolved[resolved.length - 1] !== path.sep) | ||
| 1376 | - resolved += '/'; | ||
| 1377 | 1387 | const outURL = new URL('file://'); | |
| 1378 | - if (resolved.includes('%')) | ||
| 1379 | - resolved = resolved.replace(percentRegEx, '%25'); | ||
| 1380 | - // In posix, "/" is a valid character in paths | ||
| 1381 | - if (!isWindows && resolved.includes('\\')) | ||
| 1382 | - resolved = resolved.replace(backslashRegEx, '%5C'); | ||
| 1383 | - if (resolved.includes('\n')) | ||
| 1384 | - resolved = resolved.replace(newlineRegEx, '%0A'); | ||
| 1385 | - if (resolved.includes('\r')) | ||
| 1386 | - resolved = resolved.replace(carriageReturnRegEx, '%0D'); | ||
| 1387 | - if (resolved.includes('\t')) | ||
| 1388 | - resolved = resolved.replace(tabRegEx, '%09'); | ||
| 1389 | - outURL.pathname = resolved; | ||
| 1388 | + if (isWindows && filepath.startsWith('\\\\')) { | ||
| 1389 | + // UNC path format: \\server\share\resource | ||
| 1390 | + const paths = filepath.split('\\'); | ||
| 1391 | + if (paths.length <= 3) { | ||
| 1392 | + throw new ERR_INVALID_ARG_VALUE( | ||
| 1393 | + 'filepath', | ||
| 1394 | + filepath, | ||
| 1395 | + 'Missing UNC resource path' | ||
| 1396 | + ); | ||
| 1397 | + } | ||
| 1398 | + const hostname = paths[2]; | ||
| 1399 | + if (hostname.length === 0) { | ||
| 1400 | + throw new ERR_INVALID_ARG_VALUE( | ||
| 1401 | + 'filepath', | ||
| 1402 | + filepath, | ||
| 1403 | + 'Empty UNC servername' | ||
| 1404 | + ); | ||
| 1405 | + } | ||
| 1406 | + outURL.hostname = domainToASCII(hostname); | ||
| 1407 | + outURL.pathname = encodePathChars(paths.slice(3).join('/')); | ||
| 1408 | + } else { | ||
| 1409 | + let resolved = path.resolve(filepath); | ||
| 1410 | + // path.resolve strips trailing slashes so we must add them back | ||
| 1411 | + const filePathLast = filepath.charCodeAt(filepath.length - 1); | ||
| 1412 | + if ((filePathLast === CHAR_FORWARD_SLASH || | ||
| 1413 | + (isWindows && filePathLast === CHAR_BACKWARD_SLASH)) && | ||
| 1414 | + resolved[resolved.length - 1] !== path.sep) | ||
| 1415 | + resolved += '/'; | ||
| 1416 | + outURL.pathname = encodePathChars(resolved); | ||
| 1417 | + } | ||
| 1390 | 1418 | return outURL; | |
| 1391 | 1419 | } | |
| 1392 | 1420 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -94,7 +94,9 @@ assert.throws(() => url.fileURLToPath('https://a/b/c'), { | |||
| 94 | 94 | // Euro sign (BMP code point) | |
| 95 | 95 | { path: 'C:\\€', fileURL: 'file:///C:/%E2%82%AC' }, | |
| 96 | 96 | // Rocket emoji (non-BMP code point) | |
| 97 | - { path: 'C:\\🚀', fileURL: 'file:///C:/%F0%9F%9A%80' } | ||
| 97 | + { path: 'C:\\🚀', fileURL: 'file:///C:/%F0%9F%9A%80' }, | ||
| 98 | + // UNC path (see https://docs.microsoft.com/en-us/archive/blogs/ie/file-uris-in-windows) | ||
| 99 | + { path: '\\\\nas\\My Docs\\File.doc', fileURL: 'file://nas/My%20Docs/File.doc' }, | ||
| 98 | 100 | ]; | |
| 99 | 101 | } else { | |
| 100 | 102 | testCases = [ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,6 +23,26 @@ const url = require('url'); | |||
| 23 | 23 | assert.ok(fileURL.includes('%25')); | |
| 24 | 24 | } | |
| 25 | 25 | ||
| 26 | + { | ||
| 27 | + if (isWindows) { | ||
| 28 | + // UNC path: \\server\share\resource | ||
| 29 | + | ||
| 30 | + // Missing server: | ||
| 31 | + assert.throws(() => url.pathToFileURL('\\\\\\no-server'), { | ||
| 32 | + code: 'ERR_INVALID_ARG_VALUE' | ||
| 33 | + }); | ||
| 34 | + | ||
| 35 | + // Missing share or resource: | ||
| 36 | + assert.throws(() => url.pathToFileURL('\\\\host'), { | ||
| 37 | + code: 'ERR_INVALID_ARG_VALUE' | ||
| 38 | + }); | ||
| 39 | + } else { | ||
| 40 | + // UNC paths on posix are considered a single path that has backslashes: | ||
| 41 | + const fileURL = url.pathToFileURL('\\\\nas\\share\\path.txt').href; | ||
| 42 | + assert.match(fileURL, /file:\/\/.+%5C%5Cnas%5Cshare%5Cpath\.txt$/); | ||
| 43 | + } | ||
| 44 | + } | ||
| 45 | + | ||
| 26 | 46 | { | |
| 27 | 47 | let testCases; | |
| 28 | 48 | if (isWindows) { | |
@@ -68,7 +88,9 @@ const url = require('url'); | |||
| 68 | 88 | // Euro sign (BMP code point) | |
| 69 | 89 | { path: 'C:\\€', expected: 'file:///C:/%E2%82%AC' }, | |
| 70 | 90 | // Rocket emoji (non-BMP code point) | |
| 71 | - { path: 'C:\\🚀', expected: 'file:///C:/%F0%9F%9A%80' } | ||
| 91 | + { path: 'C:\\🚀', expected: 'file:///C:/%F0%9F%9A%80' }, | ||
| 92 | + // UNC path (see https://docs.microsoft.com/en-us/archive/blogs/ie/file-uris-in-windows) | ||
| 93 | + { path: '\\\\nas\\My Docs\\File.doc', expected: 'file://nas/My%20Docs/File.doc' } | ||
| 72 | 94 | ]; | |
| 73 | 95 | } else { | |
| 74 | 96 | testCases = [ | |
| Back | FazBrowse Home | New Git URL |
0 commit comments