Fix Set-Location failure with special characters when switching drives by yotsuda · Pull Request #26510 · PowerShell/PowerShell · GitHub
Skip to content

Fix Set-Location failure with special characters when switching drives - #26510

Closed
Yoshifumi (yotsuda) wants to merge 5 commits into
PowerShell:masterfrom
yotsuda:fix/issue-25282-set-location-special-chars
Closed

Yoshifumi (yotsuda) wants to merge 5 commits into
PowerShell:masterfrom
yotsuda:fix/issue-25282-set-location-special-chars

Conversation

@yotsuda

@yotsuda Yoshifumi (yotsuda) commented Nov 22, 2025 •

Copy link
Copy Markdown
Contributor

PR Summary

Fix Set-Location failure when switching drives to restore paths containing special characters like brackets.

PR Context

Fixes #25282

When switching drives using drive-letter-only syntax (e.g., E:), PowerShell attempts to restore the previous location on that drive from CurrentLocation. However, if the path contains special characters like brackets, wildcard expansion incorrectly interprets them as wildcard patterns, causing Set-Location to fail with "Cannot find path" error.

Before this fix:

# Navigate to a directory with brackets
md "E:\Test [Folder] with brackets"
cd 'E:\Test `[Folder`] with brackets'

# Switch to another drive
C:

# Try to switch back - FAILS
E:
# Error: Set-Location: Cannot find path 'E:\Test [Folder] with brackets' because it does not exist.

After this fix:

# Navigate to a directory with brackets
md "E:\Test [Folder] with brackets"
cd 'E:\Test `[Folder`] with brackets'

# Switch to another drive
C:

# Switch back - WORKS
E:
# Successfully restored to: E:\Test [Folder] with brackets

PR Checklist

Description

Root Cause

When switching drives with syntax like E:, PowerShell restores the drive's current location by combining the drive letter with the path stored in CurrentDrive.CurrentLocation. This restored path is then processed through the normal path resolution logic, which performs wildcard expansion on special characters.

For paths containing brackets (e.g., E:\Test [Folder]), the brackets are interpreted as wildcard character classes, causing path resolution to fail.

Solution

This PR treats paths restored from drive's CurrentLocation as literal paths by suppressing wildcard expansion, similar to how -LiteralPath parameter works.

Implementation:

  1. Added pathRestoredFromDrive flag to track when a path is restored from a drive's CurrentLocation
  2. Set context.SuppressWildcardExpansion = true when pathRestoredFromDrive is true
  3. This ensures special characters in restored paths are treated literally, not as wildcard patterns

Files Changed

  • src/System.Management.Automation/engine/SessionStateLocationAPIs.cs - Added path restoration tracking and wildcard suppression
  • test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 - Added comprehensive test coverage

Testing

Test Coverage

Added 10 comprehensive test cases covering:

  1. Basic navigation with escaped brackets

    • Verifies that escaped paths work for initial navigation
  2. Physical drive ↔ C: drive switching (3 tests)

    • Physical drive → C: → Physical drive restoration
    • C: → Physical drive → C: restoration
    • Multiple round-trips between drives
  3. PSDrive ↔ C: drive switching (3 tests)

    • PSDrive → C: → PSDrive restoration
    • C: → PSDrive → C: restoration
    • Multiple round-trips between PSDrive and C:
  4. Same-drive navigation (3 tests)

    • Physical drive same-drive cd (e.g., T: when already on T:)
    • C: drive same-drive cd (e.g., C: when already on C:)
    • PSDrive same-drive cd (e.g., TestPS: when already on TestPS:)

Test Environment

  • Physical drives: Uses subst command to create temporary physical drives (1-character names: T, U, V, etc.)
  • PSDrive: Uses New-PSDrive to create drives with multi-character names (e.g., "TestPS")
  • Special characters: Tests focus on brackets [] as the primary problematic characters

Manual Testing

# Test 1: Physical drive with brackets
subst T: $env:TEMP
md "T:\Test [Folder]"
cd 'T:\Test `[Folder`]'
C:
T:  # Should restore to T:\Test [Folder]
(Get-Location).Path  # Should be: T:\Test [Folder]

# Test 2: PSDrive with brackets
New-PSDrive -Name MyDrive -PSProvider FileSystem -Root $env:TEMP
md "$env:TEMP\Test [Folder]"
cd 'MyDrive:\Test `[Folder`]'
C:
MyDrive:  # Should restore to MyDrive:\Test [Folder]
(Get-Location).Path  # Should include: Test [Folder]

# Test 3: Same-drive navigation
cd 'C:\Temp\Test `[Folder`]'
C:  # Should stay in C:\Temp\Test [Folder]
(Get-Location).Path  # Should be: C:\Temp\Test [Folder]

Automated Tests

All 10 tests pass successfully:

Context Set-Location with special characters in path
  [+] Should navigate to directory with brackets using escaped path
  [+] Should restore path with brackets when switching from physical drive to C: and back
  [+] Should restore path with brackets when switching from C: to physical drive and back
  [+] Should handle multiple round-trips between drives with special characters
  [+] Should restore path with brackets when switching from PSDrive to C: and back
  [+] Should restore path with brackets when switching from C: to PSDrive and back
  [+] Should handle multiple round-trips between PSDrive and C: with special characters
  [+] Should not change location when using same-drive syntax on current drive
  [+] Should not change location when using same-drive syntax on C: drive
  [+] Should not change location when using same-drive syntax on PSDrive

Tests Passed: 31, Failed: 0

Additional Notes

  • This fix does not affect normal path operations or -LiteralPath usage
  • Only paths automatically restored from drive's CurrentLocation are affected
  • The behavior now matches user expectations: drive switching should preserve the exact path, regardless of special characters
  • No breaking changes - this fix only corrects previously broken behavior

…cters when switching drives

When switching drives using drive-letter-only syntax (e.g., `E:`), PowerShell
attempts to restore the current location on that drive. However, if the path
contains special characters like brackets, wildcard expansion incorrectly
interprets them, causing Set-Location to fail with "Cannot find path" error.

This fix suppresses wildcard expansion when restoring paths from drive current
locations, treating them as literal paths to preserve special characters.

Changes:
- Added pathRestoredFromDrive flag to track when path is restored from drive
- Set SuppressWildcardExpansion when path comes from drive's CurrentLocation
- Added test case for drive switching with special characters in path

Fixes PowerShell#25282
Comment thread src/System.Management.Automation/engine/SessionStateLocationAPIs.cs Outdated
@iSazonov Ilya (iSazonov) added the CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log label Nov 22, 2025
- Combine nested if statements into single condition with && operator
- Remove issue reference comment from test (context name is sufficient)
@yotsuda
Yoshifumi (yotsuda) force-pushed the fix/issue-25282-set-location-special-chars branch from 50c9504 to fd9d16d Compare November 22, 2025 10:46
Comment thread test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 Outdated
Comment thread test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 Outdated
- Remove Windows-specific subst tests
- Remove $script: prefixes (Pester handles scope automatically)
- Replace physical drive tests with PSDrive-based tests
- Add regression tests for cd ., cd .., cd drive:., cd drive:..
- Tests now run on all platforms (Windows/Linux/macOS)

Addresses feedback from @iSazonov:
- Line 135: Remove $script: prefixes
- Line 151: Support non-Windows platforms via PSDrive

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a bug where Set-Location fails when switching drives to paths containing special characters like brackets. The issue occurred because PowerShell was treating restored paths as wildcard patterns instead of literal paths, causing bracket characters to be interpreted as wildcard character classes.

Key changes:

  • Added pathRestoredFromDrive flag to track when paths are restored from a drive's CurrentLocation
  • Suppresses wildcard expansion for restored paths by setting context.SuppressWildcardExpansion = true
  • Added comprehensive test coverage for various drive-switching scenarios with special characters

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/System.Management.Automation/engine/SessionStateLocationAPIs.cs Core fix: tracks path restoration from drive's CurrentLocation and suppresses wildcard expansion for these paths
test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 Comprehensive test suite covering drive switching with special characters in paths, including multiple round-trip scenarios

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 Outdated
Comment thread test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 Outdated
Yoshifumi (yotsuda) and others added 2 commits November 24, 2025 14:44
…cation.Tests.ps1

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…cation.Tests.ps1

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@iSazonov

Copy link
Copy Markdown
Collaborator

Yoshifumi (@yotsuda) After looking original issue I see WG conclusion was to fix embedded functions like function:c ( I can find them by SetDriveScriptBlock key). And looking proposed fix I think it is not right direction.

@yotsuda

Copy link
Copy Markdown
Contributor Author

Ilya (@iSazonov) Thanks for the review and clarification!
If the proposed direction is not appropriate, please feel free to close this PR.
I appreciate your guidance.

@iSazonov

Copy link
Copy Markdown
Collaborator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Set-Location fails for paths with special characters when switching drives

3 participants