Auto-escape MSBuild special characters in MsBuildArgument#2729
Auto-escape MSBuild special characters in MsBuildArgument#2729Gal-lankri wants to merge 3 commits intodotnet:masterfrom
Conversation
|
@dotnet-policy-service agree |
|
@Gal-lankri |
|
@timcassell sorry that's was by mistake. I will fix that. |
6254559 to
f61f235
Compare
| public MsBuildArgument(string value) : base(value) { } | ||
| private static readonly Dictionary<char, string> MsBuildEscapes = new () | ||
| { | ||
| { '%', "%25" }, |
There was a problem hiding this comment.
If anyone has already escaped their arguments, this will break them. Is there a way to avoid any breaks?
There was a problem hiding this comment.
Great point — thanks for flagging that!
You're absolutely right: blindly escaping everything could break cases where users already passed escaped values like %3B or %25.
To handle this safely, I updated the implementation to:
- Detect and preserve only escape sequences that match known MSBuild-escaped values (like
%3B,%24, etc.) - This prevents double-escaping for cases where users already encoded special characters, while still escaping unescaped input correctly
Additionally, if preferred, I can also add a bool alreadyEscaped = false parameter to the MsBuildArgument constructor. That way:
- Power users can bypass escaping entirely if they know their input is already safe
- Default behavior remains user-friendly for most use cases
Let me know if you'd prefer we add that constructor overload as well. Happy to follow up with it!
There was a problem hiding this comment.
It can get weird if someone puts 100%25, it's ambiguous to us whether it should be 100% or 100%25. I think it would be better to add a bool escapeSpecialChars = true param (or false default to preserve existing behavior), and don't try to parse for existing escapes.
There was a problem hiding this comment.
Yes, good point, thank you!
You're right, there's no reliable way to guess the user's intent in edge cases like 100%25. Maybe it's smarter to let the user to decide.
I've updated the implementation to:
- Add a
bool escapeSpecialChars = trueparameter to theMsBuildArgumentconstructor - If
true, the value is escaped - If
false, the value is passed through exactly as provided (for pre-escaped input)
This avoids ambiguity and doesn't change the default behavior for existing users.
|
This issue is tracked by #2719 also. I though it's better to separate MSBuildArgument's Because Additionally, It seems escape is needed when passing MSBuild parameter with |
That's a good point.
Seems like a good reason to not escape by default. Users should opt-in rather than opt-out. |
Summary
This PR adds automatic escaping of MSBuild-reserved characters in the
MsBuildArgumentclass (e.g.,;,%,$,@, etc.), so users no longer need to manually encode these characters when passing MSBuild parameters.Why
Previously, developers had to encode characters like semicolons manually (
;→%3B). This PR improves usability and correctness when passing multiple values to MSBuild properties such asDefineConstants.Changes
MsBuildArgumentconstructor to auto-escape special characters[Theory]-based test (EscapesSpecialCharactersCorrectly) to cover:Example