@joebigelow / wix / commits / d2615753

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" />