@@ -174,60 +174,46 @@ FS.staticInit();
174174 path = PATH_FS . resolve ( path ) ;
175175
176176 if ( ! path ) return { path : '' , node : null } ;
177+ opts . follow_mount ??= true
177178
178- var defaults = {
179- follow_mount : true ,
180- recurse_count : 0
181- } ;
182- opts = Object . assign ( defaults , opts )
183-
184- if ( opts . recurse_count > 8 ) { // max recursive lookup of 8
185- throw new FS . ErrnoError ( { { { cDefs. ELOOP } } } ) ;
186- }
179+ // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
180+ linkloop : for ( var nlinks = 0 ; nlinks < 40 ; nlinks ++ ) {
181+ // split the absolute path
182+ var parts = path . split ( '/' ) . filter ( ( p ) => ! ! p ) ;
187183
188- // split the absolute path
189- var parts = path . split ( '/' ) . filter ( ( p ) => ! ! p ) ;
184+ // start at the root
185+ var current = FS . root ;
186+ var current_path = '/' ;
190187
191- // start at the root
192- var current = FS . root ;
193- var current_path = '/' ;
194-
195- for ( var i = 0 ; i < parts . length ; i ++ ) {
196- var islast = ( i === parts . length - 1 ) ;
197- if ( islast && opts . parent ) {
198- // stop resolving
199- break;
200- }
188+ for ( var i = 0 ; i < parts . length ; i ++ ) {
189+ var islast = ( i === parts . length - 1 ) ;
190+ if ( islast && opts . parent ) {
191+ // stop resolving
192+ break;
193+ }
201194
202- current = FS . lookupNode ( current , parts [ i ] ) ;
203- current_path = PATH . join2 ( current_path , parts [ i ] ) ;
195+ current = FS . lookupNode ( current , parts [ i ] ) ;
196+ current_path = PATH . join2 ( current_path , parts [ i ] ) ;
204197
205- // jump to the mount's root node if this is a mountpoint
206- if ( FS . isMountpoint ( current ) ) {
207- if ( ! islast || ( islast && opts . follow_mount ) ) {
198+ // jump to the mount's root node if this is a mountpoint
199+ if ( FS . isMountpoint ( current ) && ( ! islast || opts . follow_mount ) ) {
208200 current = current . mounted . root ;
209201 }
210- }
211-
212- // by default, lookupPath will not follow a symlink if it is the final path component.
213- // setting opts.follow = true will override this behavior.
214- if ( ! islast || opts . follow ) {
215- var count = 0 ;
216- while ( FS . isLink ( current . mode ) ) {
217- var link = FS . readlink ( current_path ) ;
218- current_path = PATH_FS . resolve ( PATH . dirname ( current_path ) , link ) ;
219202
220- var lookup = FS . lookupPath ( current_path , { recurse_count : opts . recurse_count + 1 } ) ;
221- current = lookup . node ;
222-
223- if ( count ++ > 40 ) { // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
224- throw new FS . ErrnoError ( { { { cDefs. ELOOP } } } ) ;
203+ // by default, lookupPath will not follow a symlink if it is the final path component.
204+ // setting opts.follow = true will override this behavior.
205+ if ( FS . isLink ( current . mode ) && ( ! islast || opts . follow ) ) {
206+ if ( ! current . node_ops . readlink ) {
207+ throw new FS . ErrnoError ( { { { cDefs . ENOSYS } } } ) ;
225208 }
209+ var link = current . node_ops . readlink ( current ) ;
210+ path = PATH_FS . resolve ( PATH . dirname ( current_path ) , link , ...parts . slice ( i + 1 ) ) ;
211+ continue linkloop ;
226212 }
227213 }
214+ return { path : current_path , node : current } ;
228215 }
229-
230- return { path : current_path , node : current } ;
216+ throw new FS . ErrnoError ( { { { cDefs. ELOOP } } } ) ;
231217 } ,
232218 getPath ( node ) {
233219 var path ;
0 commit comments