@@ -568,8 +568,13 @@ export class FileReader {
568568 'terminal_logs' ,
569569 ] ;
570570
571- private getFilesRecursive ( dirPath : string , basePath : string ) : FileInfo [ ] {
571+ private getFilesRecursive (
572+ dirPath : string ,
573+ basePath : string ,
574+ baseReal ?: string
575+ ) : FileInfo [ ] {
572576 try {
577+ const resolvedBase = baseReal ?? fs . realpathSync ( basePath ) ;
573578 const files = fs . readdirSync ( dirPath ) ;
574579 const result : FileInfo [ ] = [ ] ;
575580
@@ -579,25 +584,43 @@ export class FileReader {
579584 if ( this . hiddenFolders . includes ( file ) ) continue ;
580585
581586 const filePath = path . join ( dirPath , file ) ;
582- const stats = fs . statSync ( filePath ) ;
583- const isFolder = stats . isDirectory ( ) ;
584- const relativePath = path . relative ( basePath , dirPath ) ;
585-
586- const fileInfo : FileInfo = {
587- path : filePath ,
588- name : file ,
589- type : isFolder
590- ? 'folder'
591- : file . split ( '.' ) . pop ( ) ?. toLowerCase ( ) || '' ,
592- isFolder : isFolder ,
593- relativePath : relativePath === '' ? '' : relativePath ,
594- } ;
595-
596- result . push ( fileInfo ) ;
597-
598- if ( isFolder ) {
599- const subFiles = this . getFilesRecursive ( filePath , basePath ) ;
600- result . push ( ...subFiles ) ;
587+ try {
588+ const stats = fs . lstatSync ( filePath ) ;
589+ if ( stats . isSymbolicLink ( ) ) continue ;
590+ const realPath = fs . realpathSync ( filePath ) ;
591+ const relativeToBase = path . relative ( resolvedBase , realPath ) ;
592+ if (
593+ relativeToBase . startsWith ( '..' ) ||
594+ path . isAbsolute ( relativeToBase )
595+ ) {
596+ continue ;
597+ }
598+ const isFolder = stats . isDirectory ( ) ;
599+ const relativePath = path . relative ( basePath , dirPath ) ;
600+
601+ const fileInfo : FileInfo = {
602+ path : filePath ,
603+ name : file ,
604+ type : isFolder
605+ ? 'folder'
606+ : file . split ( '.' ) . pop ( ) ?. toLowerCase ( ) || '' ,
607+ isFolder : isFolder ,
608+ relativePath : relativePath === '' ? '' : relativePath ,
609+ } ;
610+
611+ result . push ( fileInfo ) ;
612+
613+ if ( isFolder ) {
614+ const subFiles = this . getFilesRecursive (
615+ filePath ,
616+ basePath ,
617+ resolvedBase
618+ ) ;
619+ result . push ( ...subFiles ) ;
620+ }
621+ } catch ( fileErr ) {
622+ console . warn ( 'Skipping inaccessible file:' , filePath , fileErr ) ;
623+ continue ;
601624 }
602625 }
603626
0 commit comments