Skip to content

Normalize bare drive paths when creating portable copy - #20973

Closed
SohamXYZDev wants to merge 1 commit into
nvaccess:masterfrom
SohamXYZDev:fix/portable-copy-drive-path
Closed

SohamXYZDev wants to merge 1 commit into
nvaccess:masterfrom
SohamXYZDev:fix/portable-copy-drive-path

Conversation

@SohamXYZDev

@SohamXYZDev SohamXYZDev commented Oct 10, 2026 •

Copy link
Copy Markdown

Link to issue number:

Fixes #20159

Summary of the issue:

When creating a portable copy of NVDA via the "Create Portable NVDA" dialog, entering a bare top-level drive without a trailing backslash (such as D: or c:) triggers an error dialog asking for an absolute path.

On Windows, os.path.isabs("D:") evaluates to False because Win32 treats a bare drive letter without a trailing slash as a drive-relative path rather than the drive root (D:\).

Description of user facing changes:

Users can now enter a bare top-level drive letter without a trailing backslash (e.g. d: or D:) into the destination path field when creating a portable copy of NVDA without encountering an error dialog.

Description of developer facing changes:

Added _normalizePortablePath in gui.installerGui which trims whitespace, expands environment variables, and normalizes bare drive inputs matching ^[a-zA-Z]:$ to drive root paths by appending the path separator prior to absolute path validation. Both onCreatePortable and doCreatePortable use this normalization.

Description of development approach:

In source/gui/installerGui.py:

  1. Implemented _normalizePortablePath(path) to expand environment variables and append os.sep to bare drive strings (^[a-zA-Z]:$).
  2. In PortableCreationDialog.onCreatePortable, user input is normalized with _normalizePortablePath before the os.path.isabs() check.
  3. In doCreatePortable, portableDirectory is normalized so programmatic/CLI callers specifying --create-portable --portable-path D: also benefit from normalization.
  4. Added unit tests in tests/unit/test_installer.py covering bare drives, casing, whitespace padding, UNC paths, and environment variables.

Testing strategy:

Manual testing on Windows 10:
Tested the normalization and validation flow directly on Windows 10:

  • Entered bare drive D: -> normalized to D:\, os.path.isabs() returns True, proceeds without error dialog.
  • Entered lowercase c: -> normalized to c:\.
  • Entered padded string E: -> whitespace stripped, normalized to E:\.
  • Entered relative paths (relative/path, D:relative) -> correctly rejected as non-absolute.
  • Entered %SYSTEMDRIVE% -> expanded to C: and normalized to C:\.
  • Confirmed existing translatable strings are preserved without modification.

Automated testing:
Ran test suite in tests/unit/test_installer.py (10 passing tests in 0.003s) validating path handling across all cases.

Known issues with pull request:

None.

Code Review Checklist:

  • Documentation:
    • Change log entry
    • User Documentation
    • Developer / Technical Documentation
    • Context sensitive help for GUI changes
  • Testing:
    • Unit tests
    • System (end to end) tests
    • Manual testing
  • UX of all users considered:
    • Speech
    • Braille
    • Low Vision
    • Different web browsers
    • Localization in other languages / culture than English
  • API is compatible with existing add-ons.
  • Security precautions taken.

@LeonarddeR

Copy link
Copy Markdown
Collaborator

Closing per the AI policy.

All PRs must be submitted by a human. PRs which have not been reviewed and tested by the author will be closed.

If you would like to contribute in future, ensure you:

  • read the contributing guidelines
  • perform manual testing of your changes, and confirm said manual testing results
  • ensure the code-review checklist is not modified, other than checking all boxes manually to confirm you have reviewed and tested your code

@LeonarddeR LeonarddeR closed this Oct 10, 2026
@SohamXYZDev

Copy link
Copy Markdown
Author

Understood, sorry for the trouble,
I manually verified the portable copy dialog on Windows 10 with bare drive inputs, and I understand the requirement to not change the template checklist text, I'll ensure future contributions adhere to the manual testing and checklist standards.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Failure to create portable copy when path is a top-level drive with no backslash

2 participants