@@ -1585,6 +1585,10 @@ function encodeRealpathResult(result, options, err) {
1585
1585
}
1586
1586
}
1587
1587
1588
+ // This is removed from the fs exports in lib/module.js in order to make
1589
+ // sure that this stays internal.
1590
+ const realpathCacheKey = fs . realpathCacheKey = Symbol ( 'realpathCacheKey' ) ;
1591
+
1588
1592
fs . realpathSync = function realpathSync ( p , options ) {
1589
1593
if ( ! options )
1590
1594
options = { } ;
@@ -1599,6 +1603,13 @@ fs.realpathSync = function realpathSync(p, options) {
1599
1603
1600
1604
const seenLinks = { } ;
1601
1605
const knownHard = { } ;
1606
+ const cache = options [ realpathCacheKey ] ;
1607
+ const original = p ;
1608
+
1609
+ const maybeCachedResult = cache && cache . get ( p ) ;
1610
+ if ( maybeCachedResult ) {
1611
+ return maybeCachedResult ;
1612
+ }
1602
1613
1603
1614
// current character position in p
1604
1615
var pos ;
@@ -1639,39 +1650,47 @@ fs.realpathSync = function realpathSync(p, options) {
1639
1650
pos = nextPartRe . lastIndex ;
1640
1651
1641
1652
// continue if not a symlink
1642
- if ( knownHard [ base ] ) {
1653
+ if ( knownHard [ base ] || ( cache && cache . get ( base ) === base ) ) {
1643
1654
continue ;
1644
1655
}
1645
1656
1646
1657
var resolvedLink ;
1647
- var stat = fs . lstatSync ( base ) ;
1648
- if ( ! stat . isSymbolicLink ( ) ) {
1649
- knownHard [ base ] = true ;
1650
- continue ;
1651
- }
1658
+ const maybeCachedResolved = cache && cache . get ( base ) ;
1659
+ if ( maybeCachedResolved ) {
1660
+ resolvedLink = maybeCachedResolved ;
1661
+ } else {
1662
+ var stat = fs . lstatSync ( base ) ;
1663
+ if ( ! stat . isSymbolicLink ( ) ) {
1664
+ knownHard [ base ] = true ;
1665
+ continue ;
1666
+ }
1652
1667
1653
- // read the link if it wasn't read before
1654
- // dev/ino always return 0 on windows, so skip the check.
1655
- var linkTarget = null ;
1656
- if ( ! isWindows ) {
1657
- var id = stat . dev . toString ( 32 ) + ':' + stat . ino . toString ( 32 ) ;
1658
- if ( seenLinks . hasOwnProperty ( id ) ) {
1659
- linkTarget = seenLinks [ id ] ;
1668
+ // read the link if it wasn't read before
1669
+ // dev/ino always return 0 on windows, so skip the check.
1670
+ let linkTarget = null ;
1671
+ let id ;
1672
+ if ( ! isWindows ) {
1673
+ id = `${ stat . dev . toString ( 32 ) } :${ stat . ino . toString ( 32 ) } ` ;
1674
+ if ( seenLinks . hasOwnProperty ( id ) ) {
1675
+ linkTarget = seenLinks [ id ] ;
1676
+ }
1660
1677
}
1661
- }
1662
- if ( linkTarget === null ) {
1663
- fs . statSync ( base ) ;
1664
- linkTarget = fs . readlinkSync ( base ) ;
1665
- }
1666
- resolvedLink = pathModule . resolve ( previous , linkTarget ) ;
1678
+ if ( linkTarget === null ) {
1679
+ fs . statSync ( base ) ;
1680
+ linkTarget = fs . readlinkSync ( base ) ;
1681
+ }
1682
+ resolvedLink = pathModule . resolve ( previous , linkTarget ) ;
1667
1683
1668
- if ( ! isWindows ) seenLinks [ id ] = linkTarget ;
1684
+ if ( cache ) cache . set ( base , resolvedLink ) ;
1685
+ if ( ! isWindows ) seenLinks [ id ] = linkTarget ;
1686
+ }
1669
1687
1670
1688
// resolve the link, then start over
1671
1689
p = pathModule . resolve ( resolvedLink , p . slice ( pos ) ) ;
1672
1690
start ( ) ;
1673
1691
}
1674
1692
1693
+ if ( cache ) cache . set ( original , p ) ;
1675
1694
return encodeRealpathResult ( p , options ) ;
1676
1695
} ;
1677
1696
@@ -1767,8 +1786,9 @@ fs.realpath = function realpath(p, options, callback) {
1767
1786
// stat & read the link if not read before
1768
1787
// call gotTarget as soon as the link target is known
1769
1788
// dev/ino always return 0 on windows, so skip the check.
1789
+ let id ;
1770
1790
if ( ! isWindows ) {
1771
- var id = stat . dev . toString ( 32 ) + ':' + stat . ino . toString ( 32 ) ;
1791
+ id = ` ${ stat . dev . toString ( 32 ) } : ${ stat . ino . toString ( 32 ) } ` ;
1772
1792
if ( seenLinks . hasOwnProperty ( id ) ) {
1773
1793
return gotTarget ( null , seenLinks [ id ] , base ) ;
1774
1794
}
0 commit comments