@@ -27,6 +27,7 @@ const { getConstructorOf, removeColors } = require('internal/util');
2727const {
2828 ERR_ARG_NOT_ITERABLE ,
2929 ERR_INVALID_ARG_TYPE ,
30+ ERR_INVALID_ARG_VALUE ,
3031 ERR_INVALID_CALLBACK ,
3132 ERR_INVALID_FILE_URL_HOST ,
3233 ERR_INVALID_FILE_URL_PATH ,
@@ -1366,27 +1367,54 @@ const backslashRegEx = /\\/g;
13661367const newlineRegEx = / \n / g;
13671368const carriageReturnRegEx = / \r / g;
13681369const 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+
13691386function 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 += '/' ;
13771387 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+ }
13901418 return outURL ;
13911419}
13921420
0 commit comments