@@ -43,6 +43,7 @@ const internalUtil = require('internal/util');
4343const assertEncoding = internalFS . assertEncoding ;
4444const stringToFlags = internalFS . stringToFlags ;
4545const getPathFromURL = internalURL . getPathFromURL ;
46+ const { StorageObject } = require ( 'internal/querystring' ) ;
4647
4748Object . defineProperty ( exports , 'constants' , {
4849 configurable : false ,
@@ -1514,10 +1515,23 @@ fs.unwatchFile = function(filename, listener) {
15141515} ;
15151516
15161517
1517- // Regex to find the device root, including trailing slash. E.g. 'c:\\'.
1518- const splitRootRe = isWindows ?
1519- / ^ (?: [ a - z A - Z ] : | [ \\ / ] { 2 } [ ^ \\ / ] + [ \\ / ] [ ^ \\ / ] + ) ? [ \\ / ] * / :
1520- / ^ [ / ] * / ;
1518+ var splitRoot ;
1519+ if ( isWindows ) {
1520+ // Regex to find the device root on Windows (e.g. 'c:\\'), including trailing
1521+ // slash.
1522+ const splitRootRe = / ^ (?: [ a - z A - Z ] : | [ \\ / ] { 2 } [ ^ \\ / ] + [ \\ / ] [ ^ \\ / ] + ) ? [ \\ / ] * / ;
1523+ splitRoot = function splitRoot ( str ) {
1524+ return splitRootRe . exec ( str ) [ 0 ] ;
1525+ } ;
1526+ } else {
1527+ splitRoot = function splitRoot ( str ) {
1528+ for ( var i = 0 ; i < str . length ; ++ i ) {
1529+ if ( str . charCodeAt ( i ) !== 47 /*'/'*/ )
1530+ return str . slice ( 0 , i ) ;
1531+ }
1532+ return str ;
1533+ } ;
1534+ }
15211535
15221536function encodeRealpathResult ( result , options ) {
15231537 if ( ! options || ! options . encoding || options . encoding === 'utf8' )
@@ -1545,11 +1559,17 @@ if (isWindows) {
15451559 nextPart = function nextPart ( p , i ) { return p . indexOf ( '/' , i ) ; } ;
15461560}
15471561
1562+ const emptyObj = new StorageObject ( ) ;
15481563fs . realpathSync = function realpathSync ( p , options ) {
1549- options = getOptions ( options , { } ) ;
1550- handleError ( ( p = getPathFromURL ( p ) ) ) ;
1551- if ( typeof p !== 'string' )
1552- p += '' ;
1564+ if ( ! options )
1565+ options = emptyObj ;
1566+ else
1567+ options = getOptions ( options , emptyObj ) ;
1568+ if ( typeof p !== 'string' ) {
1569+ handleError ( ( p = getPathFromURL ( p ) ) ) ;
1570+ if ( typeof p !== 'string' )
1571+ p += '' ;
1572+ }
15531573 nullCheck ( p ) ;
15541574 p = pathModule . resolve ( p ) ;
15551575
@@ -1559,8 +1579,8 @@ fs.realpathSync = function realpathSync(p, options) {
15591579 return maybeCachedResult ;
15601580 }
15611581
1562- const seenLinks = { } ;
1563- const knownHard = { } ;
1582+ const seenLinks = new StorageObject ( ) ;
1583+ const knownHard = new StorageObject ( ) ;
15641584 const original = p ;
15651585
15661586 // current character position in p
@@ -1573,10 +1593,8 @@ fs.realpathSync = function realpathSync(p, options) {
15731593 var previous ;
15741594
15751595 // Skip over roots
1576- var m = splitRootRe . exec ( p ) ;
1577- pos = m [ 0 ] . length ;
1578- current = m [ 0 ] ;
1579- base = m [ 0 ] ;
1596+ current = base = splitRoot ( p ) ;
1597+ pos = current . length ;
15801598
15811599 // On windows, check that the root exists. On unix there is no need.
15821600 if ( isWindows && ! knownHard [ base ] ) {
@@ -1615,7 +1633,8 @@ fs.realpathSync = function realpathSync(p, options) {
16151633 // Use stats array directly to avoid creating an fs.Stats instance just
16161634 // for our internal use.
16171635
1618- binding . lstat ( pathModule . _makeLong ( base ) ) ;
1636+ var baseLong = pathModule . _makeLong ( base ) ;
1637+ binding . lstat ( baseLong ) ;
16191638
16201639 if ( ( statValues [ 1 /*mode*/ ] & S_IFMT ) !== S_IFLNK ) {
16211640 knownHard [ base ] = true ;
@@ -1631,13 +1650,13 @@ fs.realpathSync = function realpathSync(p, options) {
16311650 var dev = statValues [ 0 /*dev*/ ] . toString ( 32 ) ;
16321651 var ino = statValues [ 7 /*ino*/ ] . toString ( 32 ) ;
16331652 id = `${ dev } :${ ino } ` ;
1634- if ( seenLinks . hasOwnProperty ( id ) ) {
1653+ if ( seenLinks [ id ] ) {
16351654 linkTarget = seenLinks [ id ] ;
16361655 }
16371656 }
16381657 if ( linkTarget === null ) {
1639- binding . stat ( pathModule . _makeLong ( base ) ) ;
1640- linkTarget = binding . readlink ( pathModule . _makeLong ( base ) ) ;
1658+ binding . stat ( baseLong ) ;
1659+ linkTarget = binding . readlink ( baseLong ) ;
16411660 }
16421661 resolvedLink = pathModule . resolve ( previous , linkTarget ) ;
16431662
@@ -1649,10 +1668,8 @@ fs.realpathSync = function realpathSync(p, options) {
16491668 p = pathModule . resolve ( resolvedLink , p . slice ( pos ) ) ;
16501669
16511670 // Skip over roots
1652- m = splitRootRe . exec ( p ) ;
1653- pos = m [ 0 ] . length ;
1654- current = m [ 0 ] ;
1655- base = m [ 0 ] ;
1671+ current = base = splitRoot ( p ) ;
1672+ pos = current . length ;
16561673
16571674 // On windows, check that the root exists. On unix there is no need.
16581675 if ( isWindows && ! knownHard [ base ] ) {
@@ -1668,17 +1685,22 @@ fs.realpathSync = function realpathSync(p, options) {
16681685
16691686fs . realpath = function realpath ( p , options , callback ) {
16701687 callback = maybeCallback ( typeof options === 'function' ? options : callback ) ;
1671- options = getOptions ( options , { } ) ;
1672- if ( handleError ( ( p = getPathFromURL ( p ) ) , callback ) )
1673- return ;
1674- if ( typeof p !== 'string' )
1675- p += '' ;
1688+ if ( ! options )
1689+ options = emptyObj ;
1690+ else
1691+ options = getOptions ( options , emptyObj ) ;
1692+ if ( typeof p !== 'string' ) {
1693+ if ( handleError ( ( p = getPathFromURL ( p ) ) , callback ) )
1694+ return ;
1695+ if ( typeof p !== 'string' )
1696+ p += '' ;
1697+ }
16761698 if ( ! nullCheck ( p , callback ) )
16771699 return ;
16781700 p = pathModule . resolve ( p ) ;
16791701
1680- const seenLinks = { } ;
1681- const knownHard = { } ;
1702+ const seenLinks = new StorageObject ( ) ;
1703+ const knownHard = new StorageObject ( ) ;
16821704
16831705 // current character position in p
16841706 var pos ;
@@ -1689,11 +1711,8 @@ fs.realpath = function realpath(p, options, callback) {
16891711 // the partial path scanned in the previous round, with slash
16901712 var previous ;
16911713
1692- var m = splitRootRe . exec ( p ) ;
1693- pos = m [ 0 ] . length ;
1694- current = m [ 0 ] ;
1695- base = m [ 0 ] ;
1696- previous = '' ;
1714+ current = base = splitRoot ( p ) ;
1715+ pos = current . length ;
16971716
16981717 // On windows, check that the root exists. On unix there is no need.
16991718 if ( isWindows && ! knownHard [ base ] ) {
@@ -1756,7 +1775,7 @@ fs.realpath = function realpath(p, options, callback) {
17561775 var dev = statValues [ 0 /*ino*/ ] . toString ( 32 ) ;
17571776 var ino = statValues [ 7 /*ino*/ ] . toString ( 32 ) ;
17581777 id = `${ dev } :${ ino } ` ;
1759- if ( seenLinks . hasOwnProperty ( id ) ) {
1778+ if ( seenLinks [ id ] ) {
17601779 return gotTarget ( null , seenLinks [ id ] , base ) ;
17611780 }
17621781 }
@@ -1780,11 +1799,8 @@ fs.realpath = function realpath(p, options, callback) {
17801799 function gotResolvedLink ( resolvedLink ) {
17811800 // resolve the link, then start over
17821801 p = pathModule . resolve ( resolvedLink , p . slice ( pos ) ) ;
1783- var m = splitRootRe . exec ( p ) ;
1784- pos = m [ 0 ] . length ;
1785- current = m [ 0 ] ;
1786- base = m [ 0 ] ;
1787- previous = '' ;
1802+ current = base = splitRoot ( p ) ;
1803+ pos = current . length ;
17881804
17891805 // On windows, check that the root exists. On unix there is no need.
17901806 if ( isWindows && ! knownHard [ base ] ) {
0 commit comments