Skip to content

Make path::Display output user-style paths instead of verbatim #90547

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

Closed
wants to merge 3 commits into from

Conversation

ChrisDenton
Copy link
Member

Fixes #31789

Windows verbatim paths are essentially an API hack to allow smuggling NT kernel paths through the Win32 API. This allows bypassing certain historic limits of the Win32 APIs. Most users do not normally encounter them and can find it confusing if they do. However some APIs, most notably the one used by canonicalize, will return verbatim paths.

This PR changes Path::Display so that it will prefer to display user-style paths instead of verbatim. Examples of the transformations that are applied are:

Verbatim User
\\?\C:\directory\file.txt C:\directory\file.txt
\\?\UNC\server\share\file.txt \\server\share\file.txt

This will not affect verbatim device paths. I think, from a user perspective, \\?\PIPE\name and \\.\PIPE\name are equally strange and rarely encountered.

Verbatim paths are essentially an API hack to allow smuggling NT kernel paths through the Win32 API. This allows bypassing certain historic limits of the Win32 APIs. Most users do not normally encounter them and can find it confusing if they do show up.

So `Path::Display` will, in the common case, display user-style paths instead verbatim.
@rust-highfive
Copy link
Contributor

r? @yaahc

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 3, 2021
@the8472
Copy link
Member

the8472 commented Nov 3, 2021

What about paths exceeding MAX_PATH?

@ChrisDenton
Copy link
Member Author

As this is only for display, I don't think that should matter? It's not intended to be passed directly to the Windows API.

@the8472
Copy link
Member

the8472 commented Nov 3, 2021

I guess the user might copy-paste it when working on the CLI

@ChrisDenton
Copy link
Member Author

Sure. On the other hand Display is already (potentially) lossy. And if the program that it's handed to can't handle long paths then it's likely to run into difficulty in any case.

@joshtriplett
Copy link
Member

joshtriplett commented Nov 4, 2021

I do think it's reasonable to expect to be able to copy-paste a path and use it. If this is only an issue of long paths, I agree that the target program could take care of that. Are there other cases where a verbatim path is necessary for round-tripping, where the program that receives a pasted path won't be able to correct for it?

If long paths are the only case, 👍 for this change.

@ChrisDenton
Copy link
Member Author

Hmm, having thought about more in terms of copy/pasting, I do have some concerns.

  • If a path has . or .. components then these are interpreted literally for verbatim paths but are parsed lexically for other paths. However, . and .. are special so in any case they cannot be used as literal file names on a filesystem.
  • If a drive path (e.g. C:\ paths) ends with a legacy dos device (e.g. NUL) then the Windows API will convert it to \\.\NUL (aka the NUL device). But verbatim paths will treat the file name literally. Such file names will likely ruin someone's day however they're interpreted. Creating a literal file or directory named NUL on the filesystem confuses programs (including the Windows file explorer). But sending (via copy/paste) other programs a file path that magically turns into a device can also cause problems.
  • With non-verbatim paths, trailing . and (ASCII dot and space) are stripped from the the final component. But with verbatim paths they're kept.

In the last two cases, it's technically possible for applications to recover the intended meaning. After all, it's a fair assumption that a user intended C:\directory\NUL to be interpreted as they wrote it and not as \\.\NUL. Even if the Windows API disagrees for legacy reasons. On the other hand, you cannot at all rely on other applications to "correctly" interpret intent. They might or might not.

Therefore, it might be best to only do the conversion on unambiguous paths. In which case I'll need to rethink my approach here.

@ChrisDenton
Copy link
Member Author

ChrisDenton commented Nov 5, 2021

I've update this PR so that it only converts from verbatim if doing so wouldn't change the meaning of the path according to Win32 parsing rules. This essentially means scanning the path for anything that would be stripped during normal path handling, or for DOS device names that cause the path to completely change. My only concern now is that the code is nowhere near as trivial as where I started from.

@ChrisDenton
Copy link
Member Author

Ok, I think I'll close this now. My hope was to make it easy for Rust applications to display regular looking paths by default but I feel like there are too many pitfalls and adding all this on to the Display struct is doing too much behind the scenes magic.

I do think it'd be nice to have something similar but perhaps in a way that's more explicit. Perhaps in a similar way that you can choose the format of some other types. Or perhaps something else. I'm not sure.

@ChrisDenton ChrisDenton closed this Nov 6, 2021
@the8472
Copy link
Member

the8472 commented Nov 6, 2021

I do think it'd be nice to have something similar but perhaps in a way that's more explicit.

So, dunce?

@ChrisDenton
Copy link
Member Author

ChrisDenton commented Nov 6, 2021

So, dunce?

Sure! But my main motivation here was that, for example, Mac or Linux devs wouldn't have to go out of their way to do the more natural thing for Windows users. But maybe that goal is unattainable in this case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Windows paths should not be prefixed with \\?\ when displayed
5 participants