@@ -43,6 +43,7 @@ const internalUtil = require('internal/util');
43
43
const assertEncoding = internalFS . assertEncoding ;
44
44
const stringToFlags = internalFS . stringToFlags ;
45
45
const getPathFromURL = internalURL . getPathFromURL ;
46
+ const { StorageObject } = require ( 'internal/querystring' ) ;
46
47
47
48
Object . defineProperty ( exports , 'constants' , {
48
49
configurable : false ,
@@ -1514,10 +1515,23 @@ fs.unwatchFile = function(filename, listener) {
1514
1515
} ;
1515
1516
1516
1517
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
+ }
1521
1535
1522
1536
function encodeRealpathResult ( result , options ) {
1523
1537
if ( ! options || ! options . encoding || options . encoding === 'utf8' )
@@ -1545,11 +1559,17 @@ if (isWindows) {
1545
1559
nextPart = function nextPart ( p , i ) { return p . indexOf ( '/' , i ) ; } ;
1546
1560
}
1547
1561
1562
+ const emptyObj = new StorageObject ( ) ;
1548
1563
fs . 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
+ }
1553
1573
nullCheck ( p ) ;
1554
1574
p = pathModule . resolve ( p ) ;
1555
1575
@@ -1559,8 +1579,8 @@ fs.realpathSync = function realpathSync(p, options) {
1559
1579
return maybeCachedResult ;
1560
1580
}
1561
1581
1562
- const seenLinks = { } ;
1563
- const knownHard = { } ;
1582
+ const seenLinks = new StorageObject ( ) ;
1583
+ const knownHard = new StorageObject ( ) ;
1564
1584
const original = p ;
1565
1585
1566
1586
// current character position in p
@@ -1573,10 +1593,8 @@ fs.realpathSync = function realpathSync(p, options) {
1573
1593
var previous ;
1574
1594
1575
1595
// 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 ;
1580
1598
1581
1599
// On windows, check that the root exists. On unix there is no need.
1582
1600
if ( isWindows && ! knownHard [ base ] ) {
@@ -1615,7 +1633,8 @@ fs.realpathSync = function realpathSync(p, options) {
1615
1633
// Use stats array directly to avoid creating an fs.Stats instance just
1616
1634
// for our internal use.
1617
1635
1618
- binding . lstat ( pathModule . _makeLong ( base ) ) ;
1636
+ var baseLong = pathModule . _makeLong ( base ) ;
1637
+ binding . lstat ( baseLong ) ;
1619
1638
1620
1639
if ( ( statValues [ 1 /*mode*/ ] & S_IFMT ) !== S_IFLNK ) {
1621
1640
knownHard [ base ] = true ;
@@ -1631,13 +1650,13 @@ fs.realpathSync = function realpathSync(p, options) {
1631
1650
var dev = statValues [ 0 /*dev*/ ] . toString ( 32 ) ;
1632
1651
var ino = statValues [ 7 /*ino*/ ] . toString ( 32 ) ;
1633
1652
id = `${ dev } :${ ino } ` ;
1634
- if ( seenLinks . hasOwnProperty ( id ) ) {
1653
+ if ( seenLinks [ id ] ) {
1635
1654
linkTarget = seenLinks [ id ] ;
1636
1655
}
1637
1656
}
1638
1657
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 ) ;
1641
1660
}
1642
1661
resolvedLink = pathModule . resolve ( previous , linkTarget ) ;
1643
1662
@@ -1649,10 +1668,8 @@ fs.realpathSync = function realpathSync(p, options) {
1649
1668
p = pathModule . resolve ( resolvedLink , p . slice ( pos ) ) ;
1650
1669
1651
1670
// 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 ;
1656
1673
1657
1674
// On windows, check that the root exists. On unix there is no need.
1658
1675
if ( isWindows && ! knownHard [ base ] ) {
@@ -1668,17 +1685,22 @@ fs.realpathSync = function realpathSync(p, options) {
1668
1685
1669
1686
fs . realpath = function realpath ( p , options , callback ) {
1670
1687
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
+ }
1676
1698
if ( ! nullCheck ( p , callback ) )
1677
1699
return ;
1678
1700
p = pathModule . resolve ( p ) ;
1679
1701
1680
- const seenLinks = { } ;
1681
- const knownHard = { } ;
1702
+ const seenLinks = new StorageObject ( ) ;
1703
+ const knownHard = new StorageObject ( ) ;
1682
1704
1683
1705
// current character position in p
1684
1706
var pos ;
@@ -1689,11 +1711,8 @@ fs.realpath = function realpath(p, options, callback) {
1689
1711
// the partial path scanned in the previous round, with slash
1690
1712
var previous ;
1691
1713
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 ;
1697
1716
1698
1717
// On windows, check that the root exists. On unix there is no need.
1699
1718
if ( isWindows && ! knownHard [ base ] ) {
@@ -1756,7 +1775,7 @@ fs.realpath = function realpath(p, options, callback) {
1756
1775
var dev = statValues [ 0 /*ino*/ ] . toString ( 32 ) ;
1757
1776
var ino = statValues [ 7 /*ino*/ ] . toString ( 32 ) ;
1758
1777
id = `${ dev } :${ ino } ` ;
1759
- if ( seenLinks . hasOwnProperty ( id ) ) {
1778
+ if ( seenLinks [ id ] ) {
1760
1779
return gotTarget ( null , seenLinks [ id ] , base ) ;
1761
1780
}
1762
1781
}
@@ -1780,11 +1799,8 @@ fs.realpath = function realpath(p, options, callback) {
1780
1799
function gotResolvedLink ( resolvedLink ) {
1781
1800
// resolve the link, then start over
1782
1801
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 ;
1788
1804
1789
1805
// On windows, check that the root exists. On unix there is no need.
1790
1806
if ( isWindows && ! knownHard [ base ] ) {
0 commit comments