@@ -1514,6 +1514,10 @@ function encodeRealpathResult(result, options, err) {
1514
1514
}
1515
1515
}
1516
1516
1517
+ // This is removed from the fs exports in lib/module.js in order to make
1518
+ // sure that this stays internal.
1519
+ const realpathCacheKey = fs . realpathCacheKey = Symbol ( 'realpathCacheKey' ) ;
1520
+
1517
1521
fs . realpathSync = function realpathSync ( p , options ) {
1518
1522
if ( ! options )
1519
1523
options = { } ;
@@ -1528,6 +1532,13 @@ fs.realpathSync = function realpathSync(p, options) {
1528
1532
1529
1533
const seenLinks = { } ;
1530
1534
const knownHard = { } ;
1535
+ const cache = options [ realpathCacheKey ] ;
1536
+ const original = p ;
1537
+
1538
+ const maybeCachedResult = cache && cache . get ( p ) ;
1539
+ if ( maybeCachedResult ) {
1540
+ return maybeCachedResult ;
1541
+ }
1531
1542
1532
1543
// current character position in p
1533
1544
var pos ;
@@ -1568,39 +1579,47 @@ fs.realpathSync = function realpathSync(p, options) {
1568
1579
pos = nextPartRe . lastIndex ;
1569
1580
1570
1581
// continue if not a symlink
1571
- if ( knownHard [ base ] ) {
1582
+ if ( knownHard [ base ] || ( cache && cache . get ( base ) === base ) ) {
1572
1583
continue ;
1573
1584
}
1574
1585
1575
1586
var resolvedLink ;
1576
- var stat = fs . lstatSync ( base ) ;
1577
- if ( ! stat . isSymbolicLink ( ) ) {
1578
- knownHard [ base ] = true ;
1579
- continue ;
1580
- }
1587
+ const maybeCachedResolved = cache && cache . get ( base ) ;
1588
+ if ( maybeCachedResolved ) {
1589
+ resolvedLink = maybeCachedResolved ;
1590
+ } else {
1591
+ var stat = fs . lstatSync ( base ) ;
1592
+ if ( ! stat . isSymbolicLink ( ) ) {
1593
+ knownHard [ base ] = true ;
1594
+ continue ;
1595
+ }
1581
1596
1582
- // read the link if it wasn't read before
1583
- // dev/ino always return 0 on windows, so skip the check.
1584
- var linkTarget = null ;
1585
- if ( ! isWindows ) {
1586
- var id = stat . dev . toString ( 32 ) + ':' + stat . ino . toString ( 32 ) ;
1587
- if ( seenLinks . hasOwnProperty ( id ) ) {
1588
- linkTarget = seenLinks [ id ] ;
1597
+ // read the link if it wasn't read before
1598
+ // dev/ino always return 0 on windows, so skip the check.
1599
+ let linkTarget = null ;
1600
+ let id ;
1601
+ if ( ! isWindows ) {
1602
+ id = `${ stat . dev . toString ( 32 ) } :${ stat . ino . toString ( 32 ) } ` ;
1603
+ if ( seenLinks . hasOwnProperty ( id ) ) {
1604
+ linkTarget = seenLinks [ id ] ;
1605
+ }
1589
1606
}
1590
- }
1591
- if ( linkTarget === null ) {
1592
- fs . statSync ( base ) ;
1593
- linkTarget = fs . readlinkSync ( base ) ;
1594
- }
1595
- resolvedLink = pathModule . resolve ( previous , linkTarget ) ;
1607
+ if ( linkTarget === null ) {
1608
+ fs . statSync ( base ) ;
1609
+ linkTarget = fs . readlinkSync ( base ) ;
1610
+ }
1611
+ resolvedLink = pathModule . resolve ( previous , linkTarget ) ;
1596
1612
1597
- if ( ! isWindows ) seenLinks [ id ] = linkTarget ;
1613
+ if ( cache ) cache . set ( base , resolvedLink ) ;
1614
+ if ( ! isWindows ) seenLinks [ id ] = linkTarget ;
1615
+ }
1598
1616
1599
1617
// resolve the link, then start over
1600
1618
p = pathModule . resolve ( resolvedLink , p . slice ( pos ) ) ;
1601
1619
start ( ) ;
1602
1620
}
1603
1621
1622
+ if ( cache ) cache . set ( original , p ) ;
1604
1623
return encodeRealpathResult ( p , options ) ;
1605
1624
} ;
1606
1625
@@ -1696,8 +1715,9 @@ fs.realpath = function realpath(p, options, callback) {
1696
1715
// stat & read the link if not read before
1697
1716
// call gotTarget as soon as the link target is known
1698
1717
// dev/ino always return 0 on windows, so skip the check.
1718
+ let id ;
1699
1719
if ( ! isWindows ) {
1700
- var id = stat . dev . toString ( 32 ) + ':' + stat . ino . toString ( 32 ) ;
1720
+ id = ` ${ stat . dev . toString ( 32 ) } : ${ stat . ino . toString ( 32 ) } ` ;
1701
1721
if ( seenLinks . hasOwnProperty ( id ) ) {
1702
1722
return gotTarget ( null , seenLinks [ id ] , base ) ;
1703
1723
}
0 commit comments