@@ -47,6 +47,71 @@ public MonoArgument(string value) : base(value)
47
47
[ PublicAPI ]
48
48
public class MsBuildArgument : Argument
49
49
{
50
+ // Characters that need to be escaped.
51
+ // 1. Space
52
+ // 2. Comma (Special char that is used for separater for value of `-property:{name}={value}` and `-restoreProperty:{name}={value}`)
53
+ // 3. Other MSBuild special chars (https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-special-characters?view=vs-2022)
54
+ private static readonly char [ ] MSBuildCharsToEscape = [ ' ' , ',' , '%' , '$' , '@' , '\' ' , '(' , ')' , ';' , '?' , '*' ] ;
55
+
50
56
public MsBuildArgument ( string value ) : base ( value ) { }
57
+
58
+ /// <summary>
59
+ /// Gets the MSBuild argument that is used for build script.
60
+ /// </summary>
61
+ internal string GetEscapedTextRepresentation ( )
62
+ {
63
+ var originalArgument = TextRepresentation ;
64
+
65
+ // If entire argument surrounded with double quote, returns original argument.
66
+ // In this case. MSBuild special chars must be escaped by user. https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-special-characters
67
+ if ( originalArgument . StartsWith ( "\" " ) )
68
+ return originalArgument ;
69
+
70
+ // Process MSBuildArgument that contains '=' char. (e.g. `--property:{key}={value}` and `-restoreProperty:{key}={value}`)
71
+ // See: https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-command-line-reference?view=vs-2022
72
+ var values = originalArgument . Split ( [ '=' ] , 2 ) ;
73
+ if ( values . Length != 2 )
74
+ return originalArgument ;
75
+
76
+ var key = values [ 0 ] ;
77
+ var value = values [ 1 ] ;
78
+
79
+ // If value starts with `\` char. It is expected that the escaped value is specified by the user.
80
+ if ( value . StartsWith ( "\\ " ) )
81
+ return originalArgument ;
82
+
83
+ // If value don't contains special chars. return original value.
84
+ if ( value . IndexOfAny ( MSBuildCharsToEscape ) < 0 )
85
+ return originalArgument ;
86
+
87
+ return $ "{ key } ={ GetEscapedValue ( value ) } ";
88
+ }
89
+
90
+ private static string GetEscapedValue ( string value )
91
+ {
92
+ // If value starts with double quote. Trim leading/trailing double quote
93
+ if ( value . StartsWith ( "\" " ) )
94
+ value = value . Trim ( [ '"' ] ) ;
95
+
96
+ bool isWindows = true ;
97
+ #if NET
98
+ isWindows = OperatingSystem . IsWindows ( ) ;
99
+ #endif
100
+ if ( isWindows )
101
+ {
102
+ // On Windows environment.
103
+ // Returns double-quoted value. (Command line execution and `.bat` file requires escape double quote with `\`)
104
+ return $ """
105
+ \"{ value } \"
106
+ """ ;
107
+ }
108
+
109
+ // On non-Windows environment.
110
+ // Returns value that surround with `'"` and `"'`. See: https://github.com/dotnet/sdk/issues/8792#issuecomment-393756980
111
+ // It requires escape with `\` when running command with `.sh` file. )
112
+ return $ """
113
+ \'\"{ value } \"\'
114
+ """ ;
115
+ }
51
116
}
52
- }
117
+ }
0 commit comments