Prep filter for NtQueryDirectoryFile#123695
Conversation
NtQueryDirectoryFile should always be able to take filters as long as they are properly escaped for how we'll do our matching. The special directories `.` and `..` get blocked, but anything outside of that should be fair game. cc: @stephentoub
There was a problem hiding this comment.
Pull request overview
This PR refactors how filter expressions are prepared for NtQueryDirectoryFile on Windows. Instead of conservatively rejecting patterns that might be unsafe for OS-level filtering, it now escapes special DOS wildcard characters to ensure any expression (except . and ..) can be safely passed to the OS.
Changes:
- Adds expression preprocessing logic to escape special characters (
\,",<,>) forMatchType.Simplepatterns - Replaces the conservative
IsSafePatternForOSFiltercheck with a simple null check, allowing more patterns to use OS-level filtering - Removes the
IsSafePatternForOSFiltermethod and its associatedSearchValueshelper
src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Windows.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Windows.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Windows.cs
Outdated
Show resolved
Hide resolved
|
@JeremyKuhne there are 73 relevant test failures, e.g. |
src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Windows.cs
Show resolved
Hide resolved
|
I'm still confused about the FileName param in NtQueryDirectoryFile. I can't find anything backing that it follows similar rules to MatchType.Win32. How do we know that's the case? |
@jozkee Well, partially by looking at the sources when writing this all originally. :) https://learn.microsoft.com/openspecs/windows_protocols/ms-fsa/0b034646-4e23-4874-8488-2adac231ff23 talks about it. RtlIsNameInExpression is what everything calls (and we literally copy in |
src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Windows.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Windows.cs
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Windows.cs
Outdated
Show resolved
Hide resolved
...libraries/System.Runtime/tests/System.IO.FileSystem.Tests/Enumeration/FileSystemNameTests.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemName.cs
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Windows.cs
Outdated
Show resolved
Hide resolved
…/FileSystemEnumerator.Windows.cs
src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemName.cs
Show resolved
Hide resolved
| ReadOnlySpan<char> charsToEscape = ['\\', '"', '<', '>']; | ||
|
|
||
| int i = span.IndexOfAny(charsToEscape); |
There was a problem hiding this comment.
nit
| ReadOnlySpan<char> charsToEscape = ['\\', '"', '<', '>']; | |
| int i = span.IndexOfAny(charsToEscape); | |
| int i = span.IndexOfAny("\\\"<>"); |
| public void ReturnSpecialDirectories_WithExpression_ReturnsSpecialDirectory(MatchType matchType, string pattern) | ||
| { | ||
| string testDirectory = Directory.CreateDirectory(GetTestFilePath()).FullName; | ||
| string[] names = GetNames(testDirectory, pattern, matchType); |
There was a problem hiding this comment.
If this test doesn't fail, I guess we could remove if (!PlatformDetection.IsWindows10Version20348OrGreater) from the other tests too.
|
/ba-g infrastructure errors |
Co-authored-by: Stephen Toub <stoub@microsoft.com>
NtQueryDirectoryFileshould always be able to take filters as long as they are properly escaped for how we'll do our matching. The special directories.and..get blocked, but anything outside of that should be fair game.cc: @stephentoub