Repository navigation
Closed
Labels
In-PRIndicates that a PR is out for the issueIndicates that a PR is out for the issueIssue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get aideally support can be provided via other mechanisms, but sometimes folks do open an issue to get aNeeds-InvestigationThe behavior reported in the issue is unexpected and needs further investigation.The behavior reported in the issue is unexpected and needs further investigation.WG-Enginecore PowerShell engine, interpreter, and runtimecore PowerShell engine, interpreter, and runtime
Description
Prerequisites
- Write a descriptive title.
- Make sure you are able to repro it on the latest released version
- Search the existing issues.
- Refer to the FAQ.
- Refer to Differences between Windows PowerShell 5.1 and PowerShell.
Steps to reproduce
WildcardPattern.Escape() does not escape `, and as a result it's unreliable for escaping input for use in wildcard comparisons:
Define a string literal containing a single backtick character:
$string = 'abc`def'
Create an escaped copy of the string value:
$escaped = [WildcardPattern]::Escape($string)
Perform wildcard comparison and observe that it does not yield $true as expected:
$string -like $escaped
(That is: [WildcardPattern]::Escape($string) should produce a string value equivalent to 'abc``def', not return it as-is)
Expected behavior
PS> $string -like $escaped
TrueActual behavior
PS> $string -like $escaped
FalseError details
No response
Environment data
Name Value
---- -----
PSVersion 7.1.4
PSEdition Core
GitCommitId 7.1.4
OS Microsoft Windows 10.0.19042
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0Visuals
No response
Reacted by Michael Klement, Patrick Meinecke, Santiago Squarzon, BertDBBIPT, Armaan Mcleod and Giorgi Chakhidze
Metadata
Metadata
Assignees
Labels
In-PRIndicates that a PR is out for the issueIndicates that a PR is out for the issueIssue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get aideally support can be provided via other mechanisms, but sometimes folks do open an issue to get aNeeds-InvestigationThe behavior reported in the issue is unexpected and needs further investigation.The behavior reported in the issue is unexpected and needs further investigation.WG-Enginecore PowerShell engine, interpreter, and runtimecore PowerShell engine, interpreter, and runtime
Activity
lukeb1961 commentedon Oct 27, 2021
Wildcards in LIKE meant the DOS wildcard chars. Things like ?,*,[] right? I doubt back-tick is considered a wildcard needing escaping.
IISResetMe commentedon Oct 27, 2021
I'm aware that
`isn't a wildcard char in DOS, but PowerShell isn't DOS.If it doesn't need escaping, then you'd expect
'a`b' -like 'a`b'to work, no?SeeminglyScience commentedon Oct 27, 2021
Yeah it means "treat the next character as a literal" regardless of whether the next character would otherwise be treated as a literal or a wildcard.
lukeb1961 commentedon Oct 27, 2021
right. but my feeling is that it's not the [WildcardPattern] method at fault, but the -LIKE operation. It is broken.
vexx32 commentedon Oct 28, 2021
I mean... both WildcardPattern.Escape() and -like are wildcard methods (
-likemaps toWildcardPattern.IsMatch()from memory). So while one is clearly broken, it's still WildcardPattern that's broken, either way.SeeminglyScience commentedon Oct 28, 2021
And you can't really change the wildcard behavior without it being a rather large breaking change. Fixing the escape method should be bucket 3 I think.
vexx32 commentedon Oct 28, 2021
/cc Bruce Payette (@bpayette)
vexx32 commentedon Oct 28, 2021
Engine WG discussed this today, we spent a little time digging into the code to try to figure out what's going on. We think the crux of the issue is likely to be that we're doing essentially the same check two slightly different ways, depending on which API you're calling for WildcardPattern.
The first is here (note that backtick is included here):
PowerShell/src/System.Management.Automation/engine/regex.cs
Line 64 in 4ae539f
And the second is here:
PowerShell/src/System.Management.Automation/engine/regex.cs
Lines 401 to 404 in 4ae539f
The latter is used by
Escape(), along with a few other places, while the former is used when constructing the pattern object. There needs to be more investigation and testing, but it looks like the issue here may be caused by that discrepancy.14 remaining items
ArmaanMcleod commentedon Jan 30, 2025
Ilya (@iSazonov) and myself have looked into it a bit more and it should be as simple as remove backtick from SpecialChars. With recent PR change it seems to be working.
Mathias R. Jessen (@IISResetMe) When you get time would appreciate a review, this one was a funny one 😄.
ArmaanMcleod commentedon Feb 10, 2025
I've realised this as well seems to break for Argument completers which rely on
WildcardPattern.IsMatchin C#. Specifically for completers which want to complete CRLF.XUnit Repro:
Result:
If you remove backtick from
SpecialCharsthis works as expected.PowerShell on the other hand does not seem to be broken:
So I am confused 😄.
iSazonov commentedon Feb 10, 2025
Single quoted vs double quoted?
iSazonov commentedon Mar 18, 2025
Mathias R. Jessen (@IISResetMe) Do you want to pull PR with fix?
ArmaanMcleod commentedon Mar 19, 2025
Coming back to this one, I believe just escaping directly in the
WildardPattern.Escape()method was the right solution: ArmaanMcleod@8b98336With some Pester tests:
And results:
Mathias R. Jessen (@IISResetMe) Let me know if you see any problems with above 🙂.
iSazonov commentedon Mar 19, 2025
I wonder how it is true.
ArmaanMcleod commentedon Mar 19, 2025
Ilya (@iSazonov)
[WildcardPattern]::Escape('abc`def')would just turn intoabc``defafter escaping, and then it's just a direct-eqcomparison which would return true.Currently this doesn't work since
WildcardPattern.Escapeis not escaping backticks so it returns false.iSazonov commentedon Mar 19, 2025
But right side is WildcardPattern where backtick is special char and effective right string will be 'abc`def' vs effective left string 'abc``def'.
IISResetMe commentedon Mar 19, 2025
No, -eq will treat it as a normal string literal with backticks in it
Armaan Mcleod (@ArmaanMcleod) lgtm, although I'd double up on test cases where the result of Escape is passed as RHS (since that's specifically what we're aiming to correct here)
iSazonov commentedon Mar 19, 2025
So such tests useless in this context. They could be separate, although I don't see much point in that.
We need tests specifically for [WildcardPattern]::Escape() and [WildcardPattern]::UnEscape()
IISResetMe commentedon Mar 19, 2025
Fair point, agreed
ArmaanMcleod commentedon Mar 19, 2025
In that case it might be better just keeping the
-liketests in Pester and the Escape/UnEscape tests in XUnit which test the conversion.Ill create a new PR anyways and we can discuss there.
iSazonov commentedon Mar 20, 2025
Yes, it males sense to add 1-2 tests for -like in Pester and full set of xUnit tests for Escape and UnEscape methods.
microsoft-github-policy-service commentedon Mar 25, 2025
📣 Hey Mathias R. Jessen (@IISResetMe), how did we do? We would love to hear your feedback with the link below! 🗣️
🔗 https://aka.ms/PSRepoFeedback