Skip to content

Commit be334bd

Browse files
author
Kartik Raj
authored
Do not resolve symbolic links in posix locator if they exceed the count limit (#21658)
Closes #21310 Fixes interpreter discovery running forever for non-Windows OS
1 parent c256678 commit be334bd

File tree

3 files changed

+11
-4
lines changed

3 files changed

+11
-4
lines changed

src/client/pythonEnvironments/base/locators/lowLevel/posixKnownPathsLocator.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export class PosixKnownPathsLocator extends Locator<BasicEnvInfo> {
3333
// those binaries as environments.
3434
const knownDirs = (await commonPosixBinPaths()).filter((dirname) => !isPyenvShimDir(dirname));
3535
let pythonBinaries = await getPythonBinFromPosixPaths(knownDirs);
36+
traceVerbose(`Found ${pythonBinaries.length} python binaries in posix paths`);
3637

3738
// Filter out MacOS system installs of Python 2 if necessary.
3839
if (isMacPython2Deprecated) {

src/client/pythonEnvironments/common/externalDependencies.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { IDisposable, IConfigurationService } from '../../common/types';
1010
import { chain, iterable } from '../../common/utils/async';
1111
import { getOSType, OSType } from '../../common/utils/platform';
1212
import { IServiceContainer } from '../../ioc/types';
13-
import { traceVerbose } from '../../logging';
13+
import { traceError, traceVerbose } from '../../logging';
1414

1515
let internalServiceContainer: IServiceContainer;
1616
export function initializeExternalDependencies(serviceContainer: IServiceContainer): void {
@@ -93,16 +93,21 @@ export function arePathsSame(path1: string, path2: string): boolean {
9393
return normCasePath(path1) === normCasePath(path2);
9494
}
9595

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> {
9797
stats = stats ?? (await fsapi.lstat(absPath));
9898
if (stats.isSymbolicLink()) {
99+
if (count && count > 5) {
100+
traceError(`Detected a potential symbolic link loop at ${absPath}, terminating resolution.`);
101+
return absPath;
102+
}
99103
const link = await fsapi.readlink(absPath);
100104
// Result from readlink is not guaranteed to be an absolute path. For eg. on Mac it resolves
101105
// /usr/local/bin/python3.9 -> ../../../Library/Frameworks/Python.framework/Versions/3.9/bin/python3.9
102106
//
103107
// The resultant path is reported relative to the symlink directory we resolve. Convert that to absolute path.
104108
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);
106111
}
107112
return absPath;
108113
}

src/client/pythonEnvironments/common/posixUtils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import * as path from 'path';
77
import { uniq } from 'lodash';
88
import { getSearchPathEntries } from '../../common/utils/exec';
99
import { resolveSymbolicLink } from './externalDependencies';
10-
import { traceError, traceInfo } from '../../logging';
10+
import { traceError, traceInfo, traceVerbose } from '../../logging';
1111

1212
/**
1313
* Determine if the given filename looks like the simplest Python executable.
@@ -123,6 +123,7 @@ export async function getPythonBinFromPosixPaths(searchDirs: string[]): Promise<
123123
// Ensure that we have a collection of unique global binaries by
124124
// resolving all symlinks to the target binaries.
125125
try {
126+
traceVerbose(`Attempting to resolve symbolic link: ${filepath}`);
126127
const resolvedBin = await resolveSymbolicLink(filepath);
127128
if (binToLinkMap.has(resolvedBin)) {
128129
binToLinkMap.get(resolvedBin)?.push(filepath);

0 commit comments

Comments
 (0)