-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
Wrong paths from nt._getfinalpathname with DOS device selectors in the CWD #112563
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
Comments
Looking at the definition of It does look as though
However, just blanketly always running
Lastly,
I get these results:
It does look as though |
Hi, @finnagin
That is correct, but I should point out that other import os
os.chdir('C:\\')
os.stat('.') # works
os.stat('\\') # works
os.chdir('\\\\?\\C:\\')
os.stat('.') # works
os.stat('\\') # fails; cannot determine the correct root with a device selector in the CWD The thing with the UNC import nt
print(nt._getfullpathname('C:\\..')) # "C:\" <-- root remains
print(nt._getfullpathname('\\\\SERVER\\SHARE\\..')) # "\\SERVER\SHARE" <-- second component remains
print(nt._getfullpathname('\\\\?\\DEVICE\\..')) # "\\?\" <-- device removed Used to be that you could not use file or device selectors in the CWD, and still can't on the Command Prompt and other apps, but PowerShell and Python do allow it, which is nice for unmounted volumes.
Since CPython does support the file and device selectors in the CWD, it seems that in Windows built-in functions like import os
os.chdir(os.listvolumes()[0]) # first volume with GUID
os.scandir('\\Some\\Path') # fails; correct root not found, but tries to connect to a network share For argument's sake, if you were to deal with it at the That would also be more consistent with POSIX; because, I think, it resolves the symlinks when setting the CWD. ...And there's more: import os
import ntpath
os.chdir('C:\\')
ntpath.join(ntpath.abspath('.'), '..') # "C:\.." <-- this is OK
os.chdir('\\\\?\\C:\\')
ntpath.join(ntpath.abspath('.'), '..') # "\\?\C:.." <-- this is very wrong
os.chdir('\\\\?\\C:\\Path')
ntpath.join(ntpath.abspath('.'), 'BAD_FILENAME.') # "\\?\C:\Path\BAD_FILENAME." <-- this is hell on Earth if you use this path to create a file, because the dot will not be trimmed and Windows Explorer is going to show the file to you but then when you try to open or delete the file you'll get an error saying that it ain't know wacha talking 'bout because there's no file there even though you're seeing the file with your own two eyes... so...
# relative segments must not indirectly inherit
# a file selector, which prevents normalization |
This isn't strictly true - CPython doesn't care about your CWD. It just passes the string through to the operating system. It seems that the only sensible thing we can do here is to raise in I don't particularly want to add new errors like this, as I think you should be able to set the CWD to weird values if you need to. But we don't have to guarantee that the OS can handle it. It's worth noting that If we had an easy way to detect that the fast I'm inclined to close this issue, as I don't think there's anything we can do. If someone comes up with a good proposal to document the oddity I'd consider it, but we don't want to make Python's behaviour dependant on something this low level. |
Hi, @zooba
I think I get what you mean, please forgive if the term "support" was incorrect, but this is how I look at it: the currently supported Windows platforms and the Win32 APIs used do seem to all accept such paths, and CPython already has
From the SetCurrentDirectory documentation:
Just curious. Would that affect
Please keep the ability to use |
We don't offer this ability - Windows does. You'll need to ask Microsoft to support it. All we offer is access to the OS APIs, and the OS APIs are the ones that are failing to handle the path correctly.
Yes, 100%.
As I mentioned, any OS API that supports the path will work with the path, and our For your Footnotes
|
Bug report
Bug description:
In Windows if the CWD has a device selector
\\.\
or\\?\
any function dependent onnt._getfullpathname
may change the meaning of the path.That code will print
\\
and I mean 2 slashes, not an escaped one.
So if you use:
The result is
\\Some\Path
.That is an UNC network share, not a file named
Path
a couple of levels down from the root of the volume.Perhaps there are security concerns there.
And if the CWD is a volume root, or drive device root, then:
That will show
\\.\C:
which is a device block, which means
os.scandir
would raise an error with that path.CPython versions tested on:
3.12
Operating systems tested on:
Windows
The text was updated successfully, but these errors were encountered: