@@ -22,6 +22,7 @@ const assertEncoding = internalFS.assertEncoding;
2222const stringToFlags = internalFS . stringToFlags ;
2323const SyncWriteStream = internalFS . SyncWriteStream ;
2424const getPathFromURL = internalURL . getPathFromURL ;
25+ const { StorageObject } = require ( 'internal/querystring' ) ;
2526
2627Object . defineProperty ( exports , 'constants' , {
2728 configurable : false ,
@@ -1574,10 +1575,23 @@ fs.unwatchFile = function(filename, listener) {
15741575} ;
15751576
15761577
1577- // Regex to find the device root, including trailing slash. E.g. 'c:\\'.
1578- const splitRootRe = isWindows ?
1579- / ^ (?: [ a - z A - Z ] : | [ \\ / ] { 2 } [ ^ \\ / ] + [ \\ / ] [ ^ \\ / ] + ) ? [ \\ / ] * / :
1580- / ^ [ / ] * / ;
1578+ var splitRoot ;
1579+ if ( isWindows ) {
1580+ // Regex to find the device root on Windows (e.g. 'c:\\'), including trailing
1581+ // slash.
1582+ const splitRootRe = / ^ (?: [ a - z A - Z ] : | [ \\ / ] { 2 } [ ^ \\ / ] + [ \\ / ] [ ^ \\ / ] + ) ? [ \\ / ] * / ;
1583+ splitRoot = function splitRoot ( str ) {
1584+ return splitRootRe . exec ( str ) [ 0 ] ;
1585+ } ;
1586+ } else {
1587+ splitRoot = function splitRoot ( str ) {
1588+ for ( var i = 0 ; i < str . length ; ++ i ) {
1589+ if ( str . charCodeAt ( i ) !== 47 /*'/'*/ )
1590+ return str . slice ( 0 , i ) ;
1591+ }
1592+ return str ;
1593+ } ;
1594+ }
15811595
15821596function encodeRealpathResult ( result , options ) {
15831597 if ( ! options || ! options . encoding || options . encoding === 'utf8' )
@@ -1605,11 +1619,17 @@ if (isWindows) {
16051619 nextPart = function nextPart ( p , i ) { return p . indexOf ( '/' , i ) ; } ;
16061620}
16071621
1622+ const emptyObj = new StorageObject ( ) ;
16081623fs . realpathSync = function realpathSync ( p , options ) {
1609- options = getOptions ( options , { } ) ;
1610- handleError ( ( p = getPathFromURL ( p ) ) ) ;
1611- if ( typeof p !== 'string' )
1612- p += '' ;
1624+ if ( ! options )
1625+ options = emptyObj ;
1626+ else
1627+ options = getOptions ( options , emptyObj ) ;
1628+ if ( typeof p !== 'string' ) {
1629+ handleError ( ( p = getPathFromURL ( p ) ) ) ;
1630+ if ( typeof p !== 'string' )
1631+ p += '' ;
1632+ }
16131633 nullCheck ( p ) ;
16141634
16151635 p = pathModule . resolve ( p ) ;
@@ -1621,8 +1641,8 @@ fs.realpathSync = function realpathSync(p, options) {
16211641 return maybeCachedResult ;
16221642 }
16231643
1624- const seenLinks = { } ;
1625- const knownHard = { } ;
1644+ const seenLinks = new StorageObject ( ) ;
1645+ const knownHard = new StorageObject ( ) ;
16261646 const original = p ;
16271647
16281648 // current character position in p
@@ -1635,10 +1655,8 @@ fs.realpathSync = function realpathSync(p, options) {
16351655 var previous ;
16361656
16371657 // Skip over roots
1638- var m = splitRootRe . exec ( p ) ;
1639- pos = m [ 0 ] . length ;
1640- current = m [ 0 ] ;
1641- base = m [ 0 ] ;
1658+ current = base = splitRoot ( p ) ;
1659+ pos = current . length ;
16421660
16431661 // On windows, check that the root exists. On unix there is no need.
16441662 if ( isWindows && ! knownHard [ base ] ) {
@@ -1677,7 +1695,8 @@ fs.realpathSync = function realpathSync(p, options) {
16771695 // Use stats array directly to avoid creating an fs.Stats instance just
16781696 // for our internal use.
16791697
1680- binding . lstat ( pathModule . _makeLong ( base ) ) ;
1698+ var baseLong = pathModule . _makeLong ( base ) ;
1699+ binding . lstat ( baseLong ) ;
16811700
16821701 if ( ( statValues [ 1 /*mode*/ ] & S_IFMT ) !== S_IFLNK ) {
16831702 knownHard [ base ] = true ;
@@ -1693,13 +1712,13 @@ fs.realpathSync = function realpathSync(p, options) {
16931712 var dev = statValues [ 0 /*dev*/ ] . toString ( 32 ) ;
16941713 var ino = statValues [ 7 /*ino*/ ] . toString ( 32 ) ;
16951714 id = `${ dev } :${ ino } ` ;
1696- if ( seenLinks . hasOwnProperty ( id ) ) {
1715+ if ( seenLinks [ id ] ) {
16971716 linkTarget = seenLinks [ id ] ;
16981717 }
16991718 }
17001719 if ( linkTarget === null ) {
1701- binding . stat ( pathModule . _makeLong ( base ) ) ;
1702- linkTarget = binding . readlink ( pathModule . _makeLong ( base ) ) ;
1720+ binding . stat ( baseLong ) ;
1721+ linkTarget = binding . readlink ( baseLong ) ;
17031722 }
17041723 resolvedLink = pathModule . resolve ( previous , linkTarget ) ;
17051724
@@ -1711,10 +1730,8 @@ fs.realpathSync = function realpathSync(p, options) {
17111730 p = pathModule . resolve ( resolvedLink , p . slice ( pos ) ) ;
17121731
17131732 // Skip over roots
1714- m = splitRootRe . exec ( p ) ;
1715- pos = m [ 0 ] . length ;
1716- current = m [ 0 ] ;
1717- base = m [ 0 ] ;
1733+ current = base = splitRoot ( p ) ;
1734+ pos = current . length ;
17181735
17191736 // On windows, check that the root exists. On unix there is no need.
17201737 if ( isWindows && ! knownHard [ base ] ) {
@@ -1730,18 +1747,23 @@ fs.realpathSync = function realpathSync(p, options) {
17301747
17311748fs . realpath = function realpath ( p , options , callback ) {
17321749 callback = maybeCallback ( typeof options === 'function' ? options : callback ) ;
1733- options = getOptions ( options , { } ) ;
1734- if ( handleError ( ( p = getPathFromURL ( p ) ) , callback ) )
1735- return ;
1736- if ( typeof p !== 'string' )
1737- p += '' ;
1750+ if ( ! options )
1751+ options = emptyObj ;
1752+ else
1753+ options = getOptions ( options , emptyObj ) ;
1754+ if ( typeof p !== 'string' ) {
1755+ if ( handleError ( ( p = getPathFromURL ( p ) ) , callback ) )
1756+ return ;
1757+ if ( typeof p !== 'string' )
1758+ p += '' ;
1759+ }
17381760 if ( ! nullCheck ( p , callback ) )
17391761 return ;
17401762
17411763 p = pathModule . resolve ( p ) ;
17421764
1743- const seenLinks = { } ;
1744- const knownHard = { } ;
1765+ const seenLinks = new StorageObject ( ) ;
1766+ const knownHard = new StorageObject ( ) ;
17451767
17461768 // current character position in p
17471769 var pos ;
@@ -1752,11 +1774,8 @@ fs.realpath = function realpath(p, options, callback) {
17521774 // the partial path scanned in the previous round, with slash
17531775 var previous ;
17541776
1755- var m = splitRootRe . exec ( p ) ;
1756- pos = m [ 0 ] . length ;
1757- current = m [ 0 ] ;
1758- base = m [ 0 ] ;
1759- previous = '' ;
1777+ current = base = splitRoot ( p ) ;
1778+ pos = current . length ;
17601779
17611780 // On windows, check that the root exists. On unix there is no need.
17621781 if ( isWindows && ! knownHard [ base ] ) {
@@ -1819,7 +1838,7 @@ fs.realpath = function realpath(p, options, callback) {
18191838 var dev = statValues [ 0 /*ino*/ ] . toString ( 32 ) ;
18201839 var ino = statValues [ 7 /*ino*/ ] . toString ( 32 ) ;
18211840 id = `${ dev } :${ ino } ` ;
1822- if ( seenLinks . hasOwnProperty ( id ) ) {
1841+ if ( seenLinks [ id ] ) {
18231842 return gotTarget ( null , seenLinks [ id ] , base ) ;
18241843 }
18251844 }
@@ -1843,11 +1862,8 @@ fs.realpath = function realpath(p, options, callback) {
18431862 function gotResolvedLink ( resolvedLink ) {
18441863 // resolve the link, then start over
18451864 p = pathModule . resolve ( resolvedLink , p . slice ( pos ) ) ;
1846- var m = splitRootRe . exec ( p ) ;
1847- pos = m [ 0 ] . length ;
1848- current = m [ 0 ] ;
1849- base = m [ 0 ] ;
1850- previous = '' ;
1865+ current = base = splitRoot ( p ) ;
1866+ pos = current . length ;
18511867
18521868 // On windows, check that the root exists. On unix there is no need.
18531869 if ( isWindows && ! knownHard [ base ] ) {
0 commit comments