Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Windows path tweaks#8669

Merged
JeremyKuhne merged 1 commit intodotnet:masterfrom
JeremyKuhne:pathcleanup
Sep 9, 2016
Merged

Windows path tweaks#8669
JeremyKuhne merged 1 commit intodotnet:masterfrom
JeremyKuhne:pathcleanup

Conversation

@JeremyKuhne
Copy link
Member

  • Simplify the path length check to match desktop
  • Tweak IsPartiallyQualified to match desktop
  • Update wildcards to actually match what Windows supports

It came as a surprise to me, but yes, there are more wildcard characters in Windows than "*" and "?".

https://msdn.microsoft.com/en-us/library/ff469270.aspx

You can use these other wildcards from the CMD prompt as long as you quote and escape the quote if you use it. (It is a FindFirstFile thing)

@ianhays, @ericstj, @stephentoub


internal static readonly char[] InvalidPathChars =
{
'\"', '<', '>', '|', '\0',
Copy link
Member

Choose a reason for hiding this comment

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

These characters can be used in file paths passed to Win32 functions like CreateFile?

Copy link
Member Author

Choose a reason for hiding this comment

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

FindFirstFile is where the wildcards come into play- and is why we have the current ones (*, ?) broken out. We check all characters in GetFullPath.

What does or doesn't work with CreateFile is device/file system dependent. You can use most of these with pipes, for example. Null and backslash are the most "reserved" of the lot as the null terminates string logic and the backslash is the separator the object manager uses.

Copy link
Contributor

Choose a reason for hiding this comment

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

If this is changed, then I believe the function I recently modified (HasIllegalCharacters) needs to be changed as well to eliminate checks for these characters.

@ianhays
Copy link
Contributor

ianhays commented May 20, 2016

Won't this affect the behavior of some FileSystem functions? They use PathInternal.InvalidPathChars. I don't think we have tests in place to see what happens when they pass a (potentially valid) path that contains one of these unusual search characters?

I'm particularly interested in whether a search pattern with one of these is allowed and passed to the win32 functions or if it throws an error before it gets the chance.

@JeremyKuhne
Copy link
Member Author

@ianhays Only the ones that don't do the full check (which includes the wildcards). That behavior is by design so you can actually utilize wildcards where it makes sense.

Path.GetFullPath checks all characters.

internal unsafe static bool HasWildCardCharacters(string path)
{
// Question mark is part of extended syntax so we have to skip if we're extended
int startIndex = PathInternal.IsExtended(path) ? ExtendedPathPrefix.Length : 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

startIndex isn't being used anymore in the new code...

Copy link
Member Author

Choose a reason for hiding this comment

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

Whoops- thanks! I'll add some tests.

@JeremyKuhne
Copy link
Member Author

Test Innerloop CentOS7.1 Debug Build and Test please

@JeremyKuhne
Copy link
Member Author

@ianhays, @stephentoub Are you ok with this?

@ianhays
Copy link
Contributor

ianhays commented May 26, 2016

:shipit:

@stephentoub
Copy link
Member

Are the same wildcard changes being made to desktop?

@JeremyKuhne
Copy link
Member Author

@stephentoub, that's the intent

@joshfree joshfree added this to the 1.1.0 milestone Jun 20, 2016
@stephentoub
Copy link
Member

@JeremyKuhne, what's the status of this PR?

@JeremyKuhne
Copy link
Member Author

I'll update for #11293. @jamesqo

internal static readonly char[] InvalidPathChars =
{
'\"', '<', '>', '|', '\0',
'|', '\0',
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: indentation is off here

@JeremyKuhne
Copy link
Member Author

@stephentoub I've updated the PR, are you ok with this change?

internal static char[] GetInvalidPathChars() => new char[]
{
'\"', '<', '>', '|', '\0',
'|', '\0',
Copy link
Member

Choose a reason for hiding this comment

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

Nit: extra space before the first single quote

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed

@stephentoub
Copy link
Member

@ericstj, @weshaggard, thoughts on the wildcard change?

@JeremyKuhne
Copy link
Member Author

@weshaggard I thought a testproject pkgproj reference was supposed to pull in the local bits? I can't seem to get this to pull in the right binary any more- tried a direct reference to the src csproj as well but the Random and StringComparer tests can't compile.

@weshaggard
Copy link
Member

@ericstj, @weshaggard, thoughts on the wildcard change?

I don't have much context on the actual change or the risk it has but I do worry a little about the compat on desktop. @JeremyKuhne what do you think the compat risk for this change will be?

@weshaggard I thought a testproject pkgproj reference was supposed to pull in the local bits? I can't seem to get this to pull in the right binary any more- tried a direct reference to the src csproj as well but the Random and StringComparer tests can't compile.

A pkgproj reference will pull in the most appropriate asset it might be the local built or not it really depends on what the test project is building against. Does the TargetGroup for the test project match what you want it to pull from the source project?

@@ -210,8 +195,6 @@ internal static bool HasIllegalCharacters(string path)
switch (c)
{
case '"':
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it intentional '"' is still kept here when it it removed from the array?

Copy link
Member

Choose a reason for hiding this comment

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

(And assuming it's not, seems like we're missing a test.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Doh. Thanks- trying to code when sick- I did have a test and it is failing. 😷 I'm going to move the one remaining case up to the other if block.

@ericstj
Copy link
Member

ericstj commented Sep 7, 2016

I imagine this will have the effect of changing an ArgumentException to an IOException in some cases, which would make it a breaking change on Desktop that likely requires a quirk.

@JeremyKuhne
Copy link
Member Author

JeremyKuhne commented Sep 7, 2016

I don't have much context on the actual change or the risk it has but I do worry a little about the compat on desktop. @JeremyKuhne what do you think the compat risk for this change will be?

And...

I imagine this will have the effect of changing an ArgumentException to an IOException in some cases, which would make it a breaking change on Desktop that likely requires a quirk.

I think the risk is pretty low. Most places will still kick the path- the reason they're (bad and wildcard chars) separated is to allow enumerating. That said, I intend to put the change behind the existing normalization quirk on desktop.

- Simplify the path length check to match desktop
- Tweak IsPartiallyQualified to match desktop
- Update wildcards to actually match what Windows supports
@JeremyKuhne
Copy link
Member Author

A pkgproj reference will pull in the most appropriate asset it might be the local built or not it really depends on what the test project is building against. Does the TargetGroup for the test project match what you want it to pull from the source project?

I'm a bit under the weather- it was working as expected and failing as expected. Thanks.

@JeremyKuhne
Copy link
Member Author

@ericstj, @stephentoub, @weshaggard, @jamesqo Updated and green.

@stephentoub
Copy link
Member

As long as we're ok with the behavior change, LGTM.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants