Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-81790: support "UNC" device paths in ntpath.splitdrive() #91882

Merged
merged 16 commits into from Jun 10, 2022

Conversation

barneygale
Copy link
Contributor

@barneygale barneygale commented Apr 24, 2022

Adds support in ntpath.splitdrive() for DOS device paths with UNC links (beginning \\?\UNC\).

Previous patches for this bug substantially rewrote splitdrive() to improve how other oddities are handled (e.g. double slashes). This patch is more conservative: existing behaviour is maintained except when the prefixes are present.

This brings splitdrive() in line with pathlib behaviour, and consequently allows us to factor out a duplicate implementation in pathlib.

Fixes #81790 and #85871

@cpython-cla-bot
Copy link

@cpython-cla-bot cpython-cla-bot bot commented Apr 24, 2022

All commit authors signed the Contributor License Agreement.
CLA signed

@barneygale barneygale marked this pull request as ready for review Apr 24, 2022
@barneygale barneygale requested a review from brettcannon as a code owner Apr 24, 2022
@barneygale
Copy link
Contributor Author

@barneygale barneygale commented Apr 24, 2022

@eryksun have a mo to review? thanks

@Safihre
Copy link

@Safihre Safihre commented Apr 25, 2022

This also fixes my issue #85871 I think!

Lib/ntpath.py Outdated Show resolved Hide resolved
Lib/ntpath.py Outdated Show resolved Hide resolved
Lib/ntpath.py Outdated Show resolved Hide resolved
Lib/ntpath.py Outdated Show resolved Hide resolved
Lib/ntpath.py Outdated Show resolved Hide resolved
Lib/ntpath.py Outdated Show resolved Hide resolved
Lib/ntpath.py Outdated Show resolved Hide resolved
barneygale and others added 3 commits Apr 26, 2022
Co-authored-by: Eryk Sun <eryksun@gmail.com>
Co-authored-by: Eryk Sun <eryksun@gmail.com>
Co-authored-by: Eryk Sun <eryksun@gmail.com>
zooba
zooba approved these changes May 23, 2022
Copy link
Member

@zooba zooba left a comment

LGTM. Leaving unmerged because some other people have said they're looking at it as well.

@eryksun
Copy link
Contributor

@eryksun eryksun commented May 28, 2022

As was discussed in previous comments, this PR changes the behavior of ntpath.splitdrive() to restrict support for drives in extended paths to just drive-letter and GUID volume names and the "UNC" device. OTOH, "\\.\" paths will continue to support any device name as a drive.

For example, splitdrive() will no longer support any of the following builtin device names (alternate names for "C:" in this case) as a drive in an extended path:

>>> os.path.realpath('//?/BootPartition/')
'\\\\?\\C:\\'
>>> os.path.realpath('//?/Harddisk0Partition2/')
'\\\\?\\C:\\'
>>> os.path.realpath('//?/HarddiskVolume2/')
'\\\\?\\C:\\'

The existing implementation handles these as absolute paths, i.e. paths that have both a drive and a root (per the definition used by both pathlib and the C++ filesystem library):

>>> os.path.splitdrive('//?/BootPartition/')
('//?/BootPartition', '/')
>>> os.path.splitdrive('//?/Harddisk0Partition2/')
('//?/Harddisk0Partition2', '/')
>>> os.path.splitdrive('//?/HarddiskVolume2/')
('//?/HarddiskVolume2', '/')

The new restricted behavior will affect the results of ismount(), join(), split(), relpath(), and commonpath().

@barneygale
Copy link
Contributor Author

@barneygale barneygale commented May 28, 2022

Thanks Eryk, will fix.

@barneygale
Copy link
Contributor Author

@barneygale barneygale commented May 29, 2022

I've adjusted the patch so that it only affects paths beginning \\?\UNC\. Thanks again for the help Eryk.

Lib/ntpath.py Outdated Show resolved Hide resolved
Lib/ntpath.py Outdated Show resolved Hide resolved
@barneygale barneygale requested a review from serhiy-storchaka Jun 5, 2022
@brettcannon
Copy link
Member

@brettcannon brettcannon commented Jun 7, 2022

@eryksun do you approve of the PR now?

Lib/test/test_ntpath.py Outdated Show resolved Hide resolved
@barneygale
Copy link
Contributor Author

@barneygale barneygale commented Jun 9, 2022

Any other feedback @eryksun? Thanks

@eryksun
Copy link
Contributor

@eryksun eryksun commented Jun 10, 2022

As far as I can see, this PR is ready to merge.


Other problems of interest:

  • UNC and device paths that have no drive (e.g. "//server" or "//?/UNC/server") are mishandled by join(). They're invalid, but they're still absolute and should not be joined to a drive.
  • Device-path drives that end in a colon are mishandled as DOS drives by join(). For example, "//./C:" joined with "spam" should be "//./C:\spam", not a device named "C:spam".
  • Device paths that have no root are wrongly classified as relative by isabs(). UNC and device paths are always absolute, even if they lack a path on the device (e.g. "//./Volume{GUID}") or are invalid (e.g. more than two initial slashes; or no drive).

@zooba zooba merged commit 2ba0fd5 into python:main Jun 10, 2022
13 checks passed
@zooba
Copy link
Member

@zooba zooba commented Jun 10, 2022

@eryksun Could you file those other problems as new issues? Seems like we always have at least one "UNC isn't quite right" issue open, so may as well continue the tradition 😆

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.

7 participants