@@ -10,7 +10,7 @@ import { IDisposable, IConfigurationService } from '../../common/types';
10
10
import { chain , iterable } from '../../common/utils/async' ;
11
11
import { getOSType , OSType } from '../../common/utils/platform' ;
12
12
import { IServiceContainer } from '../../ioc/types' ;
13
- import { traceVerbose } from '../../logging' ;
13
+ import { traceError , traceVerbose } from '../../logging' ;
14
14
15
15
let internalServiceContainer : IServiceContainer ;
16
16
export function initializeExternalDependencies ( serviceContainer : IServiceContainer ) : void {
@@ -93,16 +93,21 @@ export function arePathsSame(path1: string, path2: string): boolean {
93
93
return normCasePath ( path1 ) === normCasePath ( path2 ) ;
94
94
}
95
95
96
- export async function resolveSymbolicLink ( absPath : string , stats ?: fsapi . Stats ) : Promise < string > {
96
+ export async function resolveSymbolicLink ( absPath : string , stats ?: fsapi . Stats , count ?: number ) : Promise < string > {
97
97
stats = stats ?? ( await fsapi . lstat ( absPath ) ) ;
98
98
if ( stats . isSymbolicLink ( ) ) {
99
+ if ( count && count > 5 ) {
100
+ traceError ( `Detected a potential symbolic link loop at ${ absPath } , terminating resolution.` ) ;
101
+ return absPath ;
102
+ }
99
103
const link = await fsapi . readlink ( absPath ) ;
100
104
// Result from readlink is not guaranteed to be an absolute path. For eg. on Mac it resolves
101
105
// /usr/local/bin/python3.9 -> ../../../Library/Frameworks/Python.framework/Versions/3.9/bin/python3.9
102
106
//
103
107
// The resultant path is reported relative to the symlink directory we resolve. Convert that to absolute path.
104
108
const absLinkPath = path . isAbsolute ( link ) ? link : path . resolve ( path . dirname ( absPath ) , link ) ;
105
- return resolveSymbolicLink ( absLinkPath ) ;
109
+ count = count ? count + 1 : 1 ;
110
+ return resolveSymbolicLink ( absLinkPath , undefined , count ) ;
106
111
}
107
112
return absPath ;
108
113
}
0 commit comments