@@ -112,80 +112,82 @@ function patcher(roots, useInternalLstatPatch = false) {
112112 // =========================================================================
113113 // fs.lstat
114114 // =========================================================================
115- fs . lstat = function lstat ( ...args ) {
116- // preserve error when calling function without required callback
117- if ( typeof args [ args . length - 1 ] !== 'function' ) {
118- return origLstat ( ...args ) ;
119- }
120- const cb = once ( args [ args . length - 1 ] ) ;
121- // override the callback
122- args [ args . length - 1 ] = function lstatCb ( err , stats ) {
123- if ( err )
124- return cb ( err ) ;
125- if ( ! stats . isSymbolicLink ( ) ) {
115+ if ( ! useInternalLstatPatch ) {
116+ fs . lstat = function lstat ( ...args ) {
117+ // preserve error when calling function without required callback
118+ if ( typeof args [ args . length - 1 ] !== 'function' ) {
119+ return origLstat ( ...args ) ;
120+ }
121+ const cb = once ( args [ args . length - 1 ] ) ;
122+ // override the callback
123+ args [ args . length - 1 ] = function lstatCb ( err , stats ) {
124+ if ( err )
125+ return cb ( err ) ;
126+ if ( ! stats . isSymbolicLink ( ) ) {
127+ // the file is not a symbolic link so there is nothing more to do
128+ return cb ( null , stats ) ;
129+ }
130+ args [ 0 ] = resolvePathLike ( args [ 0 ] ) ;
131+ if ( ! canEscape ( args [ 0 ] ) ) {
132+ // the file can not escaped the sandbox so there is nothing more to do
133+ return cb ( null , stats ) ;
134+ }
135+ return guardedReadLink ( args [ 0 ] , guardedReadLinkCb ) ;
136+ function guardedReadLinkCb ( str ) {
137+ if ( str != args [ 0 ] ) {
138+ // there are one or more hops within the guards so there is nothing more to do
139+ return cb ( null , stats ) ;
140+ }
141+ // there are no hops so lets report the stats of the real file;
142+ // we can't use origRealPath here since that function calls lstat internally
143+ // which can result in an infinite loop
144+ return unguardedRealPath ( args [ 0 ] , unguardedRealPathCb ) ;
145+ function unguardedRealPathCb ( err , str ) {
146+ if ( err ) {
147+ if ( err . code === 'ENOENT' ) {
148+ // broken link so there is nothing more to do
149+ return cb ( null , stats ) ;
150+ }
151+ return cb ( err ) ;
152+ }
153+ return origLstat ( str , cb ) ;
154+ }
155+ }
156+ } ;
157+ origLstat ( ...args ) ;
158+ } ;
159+ fs . lstatSync = function lstatSync ( ...args ) {
160+ const stats = origLstatSync ( ...args ) ;
161+ if ( ! ( stats === null || stats === void 0 ? void 0 : stats . isSymbolicLink ( ) ) ) {
126162 // the file is not a symbolic link so there is nothing more to do
127- return cb ( null , stats ) ;
163+ return stats ;
128164 }
129165 args [ 0 ] = resolvePathLike ( args [ 0 ] ) ;
130166 if ( ! canEscape ( args [ 0 ] ) ) {
131167 // the file can not escaped the sandbox so there is nothing more to do
132- return cb ( null , stats ) ;
168+ return stats ;
133169 }
134- return guardedReadLink ( args [ 0 ] , guardedReadLinkCb ) ;
135- function guardedReadLinkCb ( str ) {
136- if ( str != args [ 0 ] ) {
137- // there are one or more hops within the guards so there is nothing more to do
138- return cb ( null , stats ) ;
139- }
170+ const guardedReadLink = guardedReadLinkSync ( args [ 0 ] ) ;
171+ if ( guardedReadLink != args [ 0 ] ) {
172+ // there are one or more hops within the guards so there is nothing more to do
173+ return stats ;
174+ }
175+ try {
176+ args [ 0 ] = unguardedRealPathSync ( args [ 0 ] ) ;
140177 // there are no hops so lets report the stats of the real file;
141- // we can't use origRealPath here since that function calls lstat internally
178+ // we can't use origRealPathSync here since that function calls lstat internally
142179 // which can result in an infinite loop
143- return unguardedRealPath ( args [ 0 ] , unguardedRealPathCb ) ;
144- function unguardedRealPathCb ( err , str ) {
145- if ( err ) {
146- if ( err . code === 'ENOENT' ) {
147- // broken link so there is nothing more to do
148- return cb ( null , stats ) ;
149- }
150- return cb ( err ) ;
151- }
152- return origLstat ( str , cb ) ;
180+ return origLstatSync ( ...args ) ;
181+ }
182+ catch ( err ) {
183+ if ( err . code === 'ENOENT' ) {
184+ // broken link so there is nothing more to do
185+ return stats ;
153186 }
187+ throw err ;
154188 }
155189 } ;
156- origLstat ( ...args ) ;
157- } ;
158- fs . lstatSync = function lstatSync ( ...args ) {
159- const stats = origLstatSync ( ...args ) ;
160- if ( ! ( stats === null || stats === void 0 ? void 0 : stats . isSymbolicLink ( ) ) ) {
161- // the file is not a symbolic link so there is nothing more to do
162- return stats ;
163- }
164- args [ 0 ] = resolvePathLike ( args [ 0 ] ) ;
165- if ( ! canEscape ( args [ 0 ] ) ) {
166- // the file can not escaped the sandbox so there is nothing more to do
167- return stats ;
168- }
169- const guardedReadLink = guardedReadLinkSync ( args [ 0 ] ) ;
170- if ( guardedReadLink != args [ 0 ] ) {
171- // there are one or more hops within the guards so there is nothing more to do
172- return stats ;
173- }
174- try {
175- args [ 0 ] = unguardedRealPathSync ( args [ 0 ] ) ;
176- // there are no hops so lets report the stats of the real file;
177- // we can't use origRealPathSync here since that function calls lstat internally
178- // which can result in an infinite loop
179- return origLstatSync ( ...args ) ;
180- }
181- catch ( err ) {
182- if ( err . code === 'ENOENT' ) {
183- // broken link so there is nothing more to do
184- return stats ;
185- }
186- throw err ;
187- }
188- } ;
190+ }
189191 // =========================================================================
190192 // fs.realpath
191193 // =========================================================================
0 commit comments