WIXFEAT:4763 Change "string" variable type to literal and add "formatted".
Sean Hall committed
Aug 2, 2020 at 08:32 UTC
d26157531381aba81d2cac15e424b7e5c738253a
6 files changed
+122
-40
src/WixToolset.Core.Burn/Bind/SetVariableSearchFacade.cs
+17
-2
@@ -21,10 +21,25 @@ namespace WixToolset.Core.Burn
21
22
base.WriteXml(writer);
23
24
- if (this.SetVariableSymbol.Type != null)
24
+ if (this.SetVariableSymbol.Type != WixBundleVariableType.Unknown)
25
{
26
writer.WriteAttributeString("Value", this.SetVariableSymbol.Value);
27
- writer.WriteAttributeString("Type", this.SetVariableSymbol.Type);
27
+
28
+ switch (this.SetVariableSymbol.Type)
29
+ {
30
+ case WixBundleVariableType.Formatted:
31
+ writer.WriteAttributeString("Type", "formatted");
32
+ break;
33
+ case WixBundleVariableType.Numeric:
34
+ writer.WriteAttributeString("Type", "numeric");
35
+ break;
36
+ case WixBundleVariableType.String:
37
+ writer.WriteAttributeString("Type", "string");
38
+ break;
39
+ case WixBundleVariableType.Version:
40
+ writer.WriteAttributeString("Type", "version");
41
+ break;
42
+ }
43
}
44
45
writer.WriteEndElement();
src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
+17
-2
@@ -131,10 +131,25 @@ namespace WixToolset.Core.Burn.Bundles
131
{
132
writer.WriteStartElement("Variable");
133
writer.WriteAttributeString("Id", variable.Id.Id);
134
- if (null != variable.Type)
134
+ if (variable.Type != WixBundleVariableType.Unknown)
135
{
136
writer.WriteAttributeString("Value", variable.Value);
137
- writer.WriteAttributeString("Type", variable.Type);
137
+
138
+ switch (variable.Type)
139
+ {
140
+ case WixBundleVariableType.Formatted:
141
+ writer.WriteAttributeString("Type", "formatted");
142
+ break;
143
+ case WixBundleVariableType.Numeric:
144
+ writer.WriteAttributeString("Type", "numeric");
145
+ break;
146
+ case WixBundleVariableType.String:
147
+ writer.WriteAttributeString("Type", "string");
148
+ break;
149
+ case WixBundleVariableType.Version:
150
+ writer.WriteAttributeString("Type", "version");
151
+ break;
152
+ }
153
}
154
writer.WriteAttributeString("Hidden", variable.Hidden ? "yes" : "no");
155
writer.WriteAttributeString("Persisted", variable.Persisted ? "yes" : "no");
src/WixToolset.Core/Compiler_Bundle.cs
+57
-36
@@ -2141,7 +2141,7 @@ namespace WixToolset.Core
2141
case "":
2142
break;
2143
default:
2144
- this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, value, "button", "yes", "no"));
2144
+ this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, value, "always", "yes", "no"));
2145
break;
2146
}
2147
break;
@@ -3043,7 +3043,7 @@ namespace WixToolset.Core
3043
string condition = null;
3044
string after = null;
3045
string value = null;
3046
- string type = null;
3046
+ string typeValue = null;
3047
3048
foreach (var attrib in node.Attributes())
3049
{
@@ -3067,7 +3067,7 @@ namespace WixToolset.Core
3067
value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
3068
break;
3069
case "Type":
3070
- type = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
3070
+ typeValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
3071
break;
3072
3073
default:
@@ -3081,13 +3081,13 @@ namespace WixToolset.Core
3081
}
3082
}
3083
3084
- type = this.ValidateVariableTypeWithValue(sourceLineNumbers, type, value);
3084
+ var type = this.ValidateVariableTypeWithValue(sourceLineNumbers, node, typeValue, value);
3085
3086
this.Core.ParseForExtensionElements(node);
3087
3088
if (id == null)
3089
{
3090
- id = this.Core.CreateIdentifier("sbv", variable, condition, after, value, type);
3090
+ id = this.Core.CreateIdentifier("sbv", variable, condition, after, value, type.ToString());
3091
}
3092
3093
this.Core.CreateWixSearchSymbol(sourceLineNumbers, node.Name.LocalName, id, variable, condition, after);
@@ -3113,7 +3113,7 @@ namespace WixToolset.Core
3113
string name = null;
3114
var persisted = false;
3115
string value = null;
3116
- string type = null;
3116
+ string typeValue = null;
3117
3118
foreach (var attrib in node.Attributes())
3119
{
@@ -3140,7 +3140,7 @@ namespace WixToolset.Core
3140
value = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
3141
break;
3142
case "Type":
3143
- type = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
3143
+ typeValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
3144
break;
3145
default:
3146
this.Core.UnexpectedAttribute(node, attrib);
@@ -3162,7 +3162,7 @@ namespace WixToolset.Core
3162
this.Core.Write(ErrorMessages.ReservedNamespaceViolation(sourceLineNumbers, node.Name.LocalName, "Name", "Wix"));
3163
}
3164
3165
- type = this.ValidateVariableTypeWithValue(sourceLineNumbers, type, value);
3165
+ var type = this.ValidateVariableTypeWithValue(sourceLineNumbers, node, typeValue, value);
3166
3167
this.Core.ParseForExtensionElements(node);
3168
@@ -3178,46 +3178,67 @@ namespace WixToolset.Core
3178
}
3179
}
3180
3181
- private string ValidateVariableTypeWithValue(SourceLineNumber sourceLineNumbers, string type, string value)
3181
+ private WixBundleVariableType ValidateVariableTypeWithValue(SourceLineNumber sourceLineNumbers, XElement node, string typeValue, string value)
3182
{
3183
- var newType = type;
3184
- if (newType == null && value != null)
3183
+ WixBundleVariableType type;
3184
+ switch (typeValue)
3185
+ {
3186
+ case "formatted":
3187
+ type = WixBundleVariableType.Formatted;
3188
+ break;
3189
+ case "numeric":
3190
+ type = WixBundleVariableType.Numeric;
3191
+ break;
3192
+ case "string":
3193
+ type = WixBundleVariableType.String;
3194
+ break;
3195
+ case "version":
3196
+ type = WixBundleVariableType.Version;
3197
+ break;
3198
+ case null:
3199
+ type = WixBundleVariableType.Unknown;
3200
+ break;
3201
+ default:
3202
+ this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Type", typeValue, "formatted", "numeric", "string", "version"));
3203
+ return WixBundleVariableType.Unknown;
3204
+ }
3205
+
3206
+ if (type != WixBundleVariableType.Unknown)
3207
{
3186
- // Infer the type from the current value...
3187
- if (value.StartsWith("v", StringComparison.OrdinalIgnoreCase))
3208
+ if (value == null)
3209
{
3189
- // Version constructor does not support simple "v#" syntax so check to see if the value is
3190
- // non-negative real quick.
3191
- if (Int32.TryParse(value.Substring(1), NumberStyles.None, CultureInfo.InvariantCulture.NumberFormat, out var _))
3192
- {
3193
- newType = "version";
3194
- }
3195
- else if (Version.TryParse(value.Substring(1), out var _))
3196
- {
3197
- newType = "version";
3198
- }
3210
+ this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, "Variable", "Value", "Type"));
3211
}
3212
3201
- // Not a version, check for numeric.
3202
- if (newType == null)
3213
+ return type;
3214
+ }
3215
+ else if (value == null)
3216
+ {
3217
+ return type;
3218
+ }
3219
+
3220
+ // Infer the type from the current value...
3221
+ if (value.StartsWith("v", StringComparison.OrdinalIgnoreCase))
3222
+ {
3223
+ // Version constructor does not support simple "v#" syntax so check to see if the value is
3224
+ // non-negative real quick.
3225
+ if (Int32.TryParse(value.Substring(1), NumberStyles.None, CultureInfo.InvariantCulture.NumberFormat, out var _))
3226
{
3204
- if (Int64.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture.NumberFormat, out var _))
3205
- {
3206
- newType = "numeric";
3207
- }
3208
- else
3209
- {
3210
- newType = "string";
3211
- }
3227
+ return WixBundleVariableType.Version;
3228
+ }
3229
+ else if (Version.TryParse(value.Substring(1), out var _))
3230
+ {
3231
+ return WixBundleVariableType.Version;
3232
}
3233
}
3234
3215
- if (value == null && newType != null)
3235
+ // Not a version, check for numeric.
3236
+ if (Int64.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture.NumberFormat, out var _))
3237
{
3217
- this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, "Variable", "Value", "Type"));
3238
+ return WixBundleVariableType.Numeric;
3239
}
3240
3220
- return newType;
3241
+ return WixBundleVariableType.String;
3242
}
3243
3244
private class RemotePayload
src/test/WixToolsetTest.CoreIntegration/BadInputFixture.cs
+23
@@ -32,5 +32,28 @@ namespace WixToolsetTest.CoreIntegration
32
Assert.InRange(result.ExitCode, 2, Int32.MaxValue);
33
}
34
}
35
+
36
+ [Fact]
37
+ public void BundleVariableWithBadTypeIsRejected()
38
+ {
39
+ var folder = TestData.Get(@"TestData\BadInput");
40
+
41
+ using (var fs = new DisposableFileSystem())
42
+ {
43
+ var baseFolder = fs.GetFolder();
44
+ var intermediateFolder = Path.Combine(baseFolder, "obj");
45
+ var wixlibPath = Path.Combine(intermediateFolder, @"test.wixlib");
46
+
47
+ var result = WixRunner.Execute(new[]
48
+ {
49
+ "build",
50
+ Path.Combine(folder, "BundleVariable.wxs"),
51
+ "-intermediateFolder", intermediateFolder,
52
+ "-o", wixlibPath,
53
+ });
54
+
55
+ Assert.Equal(21, result.ExitCode);
56
+ }
57
+ }
58
}
59
}
src/test/WixToolsetTest.CoreIntegration/TestData/BadInput/BundleVariable.wxs
new
+7
@@ -0,0 +1,7 @@
1
+<?xml version="1.0" encoding="utf-8" ?>
2
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
3
+ xmlns:ex="http://www.example.com/scheams/v1/wxs">
4
+ <Fragment>
5
+ <Variable Name="BadType" Type="doesnotexist" Value="dne" />
6
+ </Fragment>
7
+</Wix>
src/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj
+1
@@ -22,6 +22,7 @@
22
<Content Include="TestData\AppSearch\NestedDirSearchUnderRegSearch.msi" CopyToOutputDirectory="PreserveNewest" />
23
<Content Include="TestData\AppSearch\RegistrySearch.wxs" CopyToOutputDirectory="PreserveNewest" />
24
<Content Include="TestData\BadEnsureTable\BadEnsureTable.wxs" CopyToOutputDirectory="PreserveNewest" />
25
+ <Content Include="TestData\BadInput\BundleVariable.wxs" CopyToOutputDirectory="PreserveNewest" />
26
<Content Include="TestData\BadInput\RegistryKey.wxs" CopyToOutputDirectory="PreserveNewest" />
27
<Content Include="TestData\BindVariables\DefaultedVariable.wxs" CopyToOutputDirectory="PreserveNewest" />
28
<Content Include="TestData\BindVariables\data\test.txt" CopyToOutputDirectory="PreserveNewest" />