@@ -343,9 +343,20 @@ export class OverlayFs implements IFileSystem {
343343 return fromBuffer ( buffer , encoding ) ;
344344 }
345345
346- async readFileBuffer ( path : string ) : Promise < Uint8Array > {
346+ async readFileBuffer (
347+ path : string ,
348+ seen : Set < string > = new Set ( ) ,
349+ ) : Promise < Uint8Array > {
347350 const normalized = this . normalizePath ( path ) ;
348351
352+ // Detect symlink loops
353+ if ( seen . has ( normalized ) ) {
354+ throw new Error (
355+ `ELOOP: too many levels of symbolic links, open '${ path } '` ,
356+ ) ;
357+ }
358+ seen . add ( normalized ) ;
359+
349360 // Check if deleted
350361 if ( this . deleted . has ( normalized ) ) {
351362 throw new Error ( `ENOENT: no such file or directory, open '${ path } '` ) ;
@@ -356,7 +367,7 @@ export class OverlayFs implements IFileSystem {
356367 if ( memEntry ) {
357368 if ( memEntry . type === "symlink" ) {
358369 const target = this . resolveSymlink ( normalized , memEntry . target ) ;
359- return this . readFileBuffer ( target ) ;
370+ return this . readFileBuffer ( target , seen ) ;
360371 }
361372 if ( memEntry . type !== "file" ) {
362373 throw new Error (
@@ -377,7 +388,7 @@ export class OverlayFs implements IFileSystem {
377388 if ( stat . isSymbolicLink ( ) ) {
378389 const target = await fs . promises . readlink ( realPath ) ;
379390 const resolvedTarget = this . resolveSymlink ( normalized , target ) ;
380- return this . readFileBuffer ( resolvedTarget ) ;
391+ return this . readFileBuffer ( resolvedTarget , seen ) ;
381392 }
382393 if ( stat . isDirectory ( ) ) {
383394 throw new Error (
@@ -451,9 +462,17 @@ export class OverlayFs implements IFileSystem {
451462 return this . existsInOverlay ( path ) ;
452463 }
453464
454- async stat ( path : string ) : Promise < FsStat > {
465+ async stat ( path : string , seen : Set < string > = new Set ( ) ) : Promise < FsStat > {
455466 const normalized = this . normalizePath ( path ) ;
456467
468+ // Detect symlink loops
469+ if ( seen . has ( normalized ) ) {
470+ throw new Error (
471+ `ELOOP: too many levels of symbolic links, stat '${ path } '` ,
472+ ) ;
473+ }
474+ seen . add ( normalized ) ;
475+
457476 if ( this . deleted . has ( normalized ) ) {
458477 throw new Error ( `ENOENT: no such file or directory, stat '${ path } '` ) ;
459478 }
@@ -464,7 +483,7 @@ export class OverlayFs implements IFileSystem {
464483 // Follow symlinks
465484 if ( entry . type === "symlink" ) {
466485 const target = this . resolveSymlink ( normalized , entry . target ) ;
467- return this . stat ( target ) ;
486+ return this . stat ( target , seen ) ;
468487 }
469488
470489 let size = 0 ;
0 commit comments