@@ -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 ,
@@ -1369,27 +1370,54 @@ const backslashRegEx = /\\/g;
13691370const newlineRegEx = / \n / g;
13701371const carriageReturnRegEx = / \r / g;
13711372const tabRegEx = / \t / g;
1373+
1374+ function encodePathChars ( filepath ) {
1375+ if ( filepath . includes ( '%' ) )
1376+ filepath = filepath . replace ( percentRegEx , '%25' ) ;
1377+ // In posix, backslash is a valid character in paths:
1378+ if ( ! isWindows && filepath . includes ( '\\' ) )
1379+ filepath = filepath . replace ( backslashRegEx , '%5C' ) ;
1380+ if ( filepath . includes ( '\n' ) )
1381+ filepath = filepath . replace ( newlineRegEx , '%0A' ) ;
1382+ if ( filepath . includes ( '\r' ) )
1383+ filepath = filepath . replace ( carriageReturnRegEx , '%0D' ) ;
1384+ if ( filepath . includes ( '\t' ) )
1385+ filepath = filepath . replace ( tabRegEx , '%09' ) ;
1386+ return filepath ;
1387+ }
1388+
13721389function pathToFileURL ( filepath ) {
1373- let resolved = path . resolve ( filepath ) ;
1374- // path.resolve strips trailing slashes so we must add them back
1375- const filePathLast = filepath . charCodeAt ( filepath . length - 1 ) ;
1376- if ( ( filePathLast === CHAR_FORWARD_SLASH ||
1377- ( isWindows && filePathLast === CHAR_BACKWARD_SLASH ) ) &&
1378- resolved [ resolved . length - 1 ] !== path . sep )
1379- resolved += '/' ;
13801390 const outURL = new URL ( 'file://' ) ;
1381- if ( resolved . includes ( '%' ) )
1382- resolved = resolved . replace ( percentRegEx , '%25' ) ;
1383- // In posix, "/" is a valid character in paths
1384- if ( ! isWindows && resolved . includes ( '\\' ) )
1385- resolved = resolved . replace ( backslashRegEx , '%5C' ) ;
1386- if ( resolved . includes ( '\n' ) )
1387- resolved = resolved . replace ( newlineRegEx , '%0A' ) ;
1388- if ( resolved . includes ( '\r' ) )
1389- resolved = resolved . replace ( carriageReturnRegEx , '%0D' ) ;
1390- if ( resolved . includes ( '\t' ) )
1391- resolved = resolved . replace ( tabRegEx , '%09' ) ;
1392- outURL . pathname = resolved ;
1391+ if ( isWindows && filepath . startsWith ( '\\\\' ) ) {
1392+ // UNC path format: \\server\share\resource
1393+ const paths = filepath . split ( '\\' ) ;
1394+ if ( paths . length <= 3 ) {
1395+ throw new ERR_INVALID_ARG_VALUE (
1396+ 'filepath' ,
1397+ filepath ,
1398+ 'Missing UNC resource path'
1399+ ) ;
1400+ }
1401+ const hostname = paths [ 2 ] ;
1402+ if ( hostname . length === 0 ) {
1403+ throw new ERR_INVALID_ARG_VALUE (
1404+ 'filepath' ,
1405+ filepath ,
1406+ 'Empty UNC servername'
1407+ ) ;
1408+ }
1409+ outURL . hostname = domainToASCII ( hostname ) ;
1410+ outURL . pathname = encodePathChars ( paths . slice ( 3 ) . join ( '/' ) ) ;
1411+ } else {
1412+ let resolved = path . resolve ( filepath ) ;
1413+ // path.resolve strips trailing slashes so we must add them back
1414+ const filePathLast = filepath . charCodeAt ( filepath . length - 1 ) ;
1415+ if ( ( filePathLast === CHAR_FORWARD_SLASH ||
1416+ ( isWindows && filePathLast === CHAR_BACKWARD_SLASH ) ) &&
1417+ resolved [ resolved . length - 1 ] !== path . sep )
1418+ resolved += '/' ;
1419+ outURL . pathname = encodePathChars ( resolved ) ;
1420+ }
13931421 return outURL ;
13941422}
13951423
0 commit comments