diff --git a/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs b/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs index e8b76de4837..cab7ed6c083 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs @@ -1139,7 +1139,7 @@ private static string AddToPath(string basePath, string pathToAdd, int insertPos int position = PathContainsSubstring(result.ToString(), subPathToAdd); // searching in effective 'result' value ensures that possible duplicates in pathsToAdd are handled correctly if (position == -1) // subPathToAdd not found - add it { - if (insertPosition == -1) // append subPathToAdd to the end + if (insertPosition == -1 || insertPosition > basePath.Length) // append subPathToAdd to the end { bool endsWithPathSeparator = false; if (result.Length > 0) @@ -1223,23 +1223,23 @@ public static string GetModulePath(string currentProcessModulePath, string hklmM // personalModulePath // sharedModulePath // systemModulePath - int insertIndex = 0; - if (!string.IsNullOrEmpty(personalModulePathToUse)) + currentProcessModulePath = AddToPath(currentProcessModulePath, personalModulePathToUse, 0); + int insertIndex = currentProcessModulePath.IndexOf(Path.PathSeparator, PathContainsSubstring(currentProcessModulePath, personalModulePathToUse)); + if (insertIndex != -1) { - currentProcessModulePath = AddToPath(currentProcessModulePath, personalModulePathToUse, insertIndex); - insertIndex = PathContainsSubstring(currentProcessModulePath, personalModulePathToUse) + personalModulePathToUse.Length + 1; + // advance past the path separator + insertIndex++; } - if (!string.IsNullOrEmpty(sharedModulePath)) + currentProcessModulePath = AddToPath(currentProcessModulePath, sharedModulePath, insertIndex); + insertIndex = currentProcessModulePath.IndexOf(Path.PathSeparator, PathContainsSubstring(currentProcessModulePath, sharedModulePath)); + if (insertIndex != -1) { - currentProcessModulePath = AddToPath(currentProcessModulePath, sharedModulePath, insertIndex); - insertIndex = PathContainsSubstring(currentProcessModulePath, sharedModulePath) + sharedModulePath.Length + 1; + // advance past the path separator + insertIndex++; } - if (!string.IsNullOrEmpty(systemModulePathToUse)) - { - currentProcessModulePath = AddToPath(currentProcessModulePath, systemModulePathToUse, insertIndex); - } + currentProcessModulePath = AddToPath(currentProcessModulePath, systemModulePathToUse, insertIndex); } return currentProcessModulePath; diff --git a/test/powershell/engine/Module/ModulePath.Tests.ps1 b/test/powershell/engine/Module/ModulePath.Tests.ps1 index b4dd5add437..a18b4fc3ffa 100644 --- a/test/powershell/engine/Module/ModulePath.Tests.ps1 +++ b/test/powershell/engine/Module/ModulePath.Tests.ps1 @@ -187,4 +187,18 @@ Describe "SxS Module Path Basic Tests" -tags "CI" { Remove-Item -Path $userConfigPath -Force } } + + It 'User PSModulePath has trailing separator' { + if ($IsWindows) { + $validation = "*\$env:SystemDrive\*" + } + else { + $validation = "*//*" + } + + $newUserPath = Join-Path $expectedUserPath ([System.IO.Path]::DirectorySeparatorChar) + $env:PSModulePath = $env:PSModulePath.Replace($expectedUserPath, $newUserPath).Replace($expectedSharedPath,"") + $out = & $powershell -noprofile -command '$env:PSModulePath' + $out.Split([System.IO.Path]::PathSeparator, [System.StringSplitOptions]::RemoveEmptyEntries) | Should -Not -BeLike $validation + } }