-
-
Notifications
You must be signed in to change notification settings - Fork 995
Auto-escape MSBuild special characters in MsBuildArgument #2729
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
base: master
Are you sure you want to change the base?
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 = true
parameter to theMsBuildArgument
constructor - 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
MsBuildArgument
class (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
MsBuildArgument
constructor to auto-escape special characters[Theory]
-based test (EscapesSpecialCharactersCorrectly
) to cover:Example