diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2020-08-02 08:32:54 -0600 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2020-08-09 10:37:12 -0600 |
commit | d26157531381aba81d2cac15e424b7e5c738253a (patch) | |
tree | 5bd5793ec90529c4be397e9034f17e35b7c9e4a2 | |
parent | 581897da13bd8a20eea0c2079262caaa06cde676 (diff) | |
download | wix-d26157531381aba81d2cac15e424b7e5c738253a.tar.gz wix-d26157531381aba81d2cac15e424b7e5c738253a.tar.bz2 wix-d26157531381aba81d2cac15e424b7e5c738253a.zip |
WIXFEAT:4763 Change "string" variable type to literal and add "formatted".
6 files changed, 122 insertions, 40 deletions
diff --git a/src/WixToolset.Core.Burn/Bind/SetVariableSearchFacade.cs b/src/WixToolset.Core.Burn/Bind/SetVariableSearchFacade.cs index fb6f72dd..e88f26ef 100644 --- a/src/WixToolset.Core.Burn/Bind/SetVariableSearchFacade.cs +++ b/src/WixToolset.Core.Burn/Bind/SetVariableSearchFacade.cs | |||
@@ -21,10 +21,25 @@ namespace WixToolset.Core.Burn | |||
21 | 21 | ||
22 | base.WriteXml(writer); | 22 | base.WriteXml(writer); |
23 | 23 | ||
24 | if (this.SetVariableSymbol.Type != null) | 24 | if (this.SetVariableSymbol.Type != WixBundleVariableType.Unknown) |
25 | { | 25 | { |
26 | writer.WriteAttributeString("Value", this.SetVariableSymbol.Value); | 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 | } | ||
28 | } | 43 | } |
29 | 44 | ||
30 | writer.WriteEndElement(); | 45 | writer.WriteEndElement(); |
diff --git a/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs b/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs index 05b15ab6..6eafcdd9 100644 --- a/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs +++ b/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs | |||
@@ -131,10 +131,25 @@ namespace WixToolset.Core.Burn.Bundles | |||
131 | { | 131 | { |
132 | writer.WriteStartElement("Variable"); | 132 | writer.WriteStartElement("Variable"); |
133 | writer.WriteAttributeString("Id", variable.Id.Id); | 133 | writer.WriteAttributeString("Id", variable.Id.Id); |
134 | if (null != variable.Type) | 134 | if (variable.Type != WixBundleVariableType.Unknown) |
135 | { | 135 | { |
136 | writer.WriteAttributeString("Value", variable.Value); | 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 | } | ||
138 | } | 153 | } |
139 | writer.WriteAttributeString("Hidden", variable.Hidden ? "yes" : "no"); | 154 | writer.WriteAttributeString("Hidden", variable.Hidden ? "yes" : "no"); |
140 | writer.WriteAttributeString("Persisted", variable.Persisted ? "yes" : "no"); | 155 | writer.WriteAttributeString("Persisted", variable.Persisted ? "yes" : "no"); |
diff --git a/src/WixToolset.Core/Compiler_Bundle.cs b/src/WixToolset.Core/Compiler_Bundle.cs index d73db84d..33467dda 100644 --- a/src/WixToolset.Core/Compiler_Bundle.cs +++ b/src/WixToolset.Core/Compiler_Bundle.cs | |||
@@ -2141,7 +2141,7 @@ namespace WixToolset.Core | |||
2141 | case "": | 2141 | case "": |
2142 | break; | 2142 | break; |
2143 | default: | 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; | 2145 | break; |
2146 | } | 2146 | } |
2147 | break; | 2147 | break; |
@@ -3043,7 +3043,7 @@ namespace WixToolset.Core | |||
3043 | string condition = null; | 3043 | string condition = null; |
3044 | string after = null; | 3044 | string after = null; |
3045 | string value = null; | 3045 | string value = null; |
3046 | string type = null; | 3046 | string typeValue = null; |
3047 | 3047 | ||
3048 | foreach (var attrib in node.Attributes()) | 3048 | foreach (var attrib in node.Attributes()) |
3049 | { | 3049 | { |
@@ -3067,7 +3067,7 @@ namespace WixToolset.Core | |||
3067 | value = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 3067 | value = this.Core.GetAttributeValue(sourceLineNumbers, attrib); |
3068 | break; | 3068 | break; |
3069 | case "Type": | 3069 | case "Type": |
3070 | type = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 3070 | typeValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib); |
3071 | break; | 3071 | break; |
3072 | 3072 | ||
3073 | default: | 3073 | default: |
@@ -3081,13 +3081,13 @@ namespace WixToolset.Core | |||
3081 | } | 3081 | } |
3082 | } | 3082 | } |
3083 | 3083 | ||
3084 | type = this.ValidateVariableTypeWithValue(sourceLineNumbers, type, value); | 3084 | var type = this.ValidateVariableTypeWithValue(sourceLineNumbers, node, typeValue, value); |
3085 | 3085 | ||
3086 | this.Core.ParseForExtensionElements(node); | 3086 | this.Core.ParseForExtensionElements(node); |
3087 | 3087 | ||
3088 | if (id == null) | 3088 | if (id == null) |
3089 | { | 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 | } | 3091 | } |
3092 | 3092 | ||
3093 | this.Core.CreateWixSearchSymbol(sourceLineNumbers, node.Name.LocalName, id, variable, condition, after); | 3093 | this.Core.CreateWixSearchSymbol(sourceLineNumbers, node.Name.LocalName, id, variable, condition, after); |
@@ -3113,7 +3113,7 @@ namespace WixToolset.Core | |||
3113 | string name = null; | 3113 | string name = null; |
3114 | var persisted = false; | 3114 | var persisted = false; |
3115 | string value = null; | 3115 | string value = null; |
3116 | string type = null; | 3116 | string typeValue = null; |
3117 | 3117 | ||
3118 | foreach (var attrib in node.Attributes()) | 3118 | foreach (var attrib in node.Attributes()) |
3119 | { | 3119 | { |
@@ -3140,7 +3140,7 @@ namespace WixToolset.Core | |||
3140 | value = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); | 3140 | value = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); |
3141 | break; | 3141 | break; |
3142 | case "Type": | 3142 | case "Type": |
3143 | type = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 3143 | typeValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib); |
3144 | break; | 3144 | break; |
3145 | default: | 3145 | default: |
3146 | this.Core.UnexpectedAttribute(node, attrib); | 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")); | 3162 | this.Core.Write(ErrorMessages.ReservedNamespaceViolation(sourceLineNumbers, node.Name.LocalName, "Name", "Wix")); |
3163 | } | 3163 | } |
3164 | 3164 | ||
3165 | type = this.ValidateVariableTypeWithValue(sourceLineNumbers, type, value); | 3165 | var type = this.ValidateVariableTypeWithValue(sourceLineNumbers, node, typeValue, value); |
3166 | 3166 | ||
3167 | this.Core.ParseForExtensionElements(node); | 3167 | this.Core.ParseForExtensionElements(node); |
3168 | 3168 | ||
@@ -3178,46 +3178,67 @@ namespace WixToolset.Core | |||
3178 | } | 3178 | } |
3179 | } | 3179 | } |
3180 | 3180 | ||
3181 | private string ValidateVariableTypeWithValue(SourceLineNumber sourceLineNumbers, string type, string value) | 3181 | private WixBundleVariableType ValidateVariableTypeWithValue(SourceLineNumber sourceLineNumbers, XElement node, string typeValue, string value) |
3182 | { | 3182 | { |
3183 | var newType = type; | 3183 | WixBundleVariableType type; |
3184 | if (newType == null && value != null) | 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) | ||
3185 | { | 3207 | { |
3186 | // Infer the type from the current value... | 3208 | if (value == null) |
3187 | if (value.StartsWith("v", StringComparison.OrdinalIgnoreCase)) | ||
3188 | { | 3209 | { |
3189 | // Version constructor does not support simple "v#" syntax so check to see if the value is | 3210 | this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, "Variable", "Value", "Type")); |
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 | } | ||
3199 | } | 3211 | } |
3200 | 3212 | ||
3201 | // Not a version, check for numeric. | 3213 | return type; |
3202 | if (newType == null) | 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 _)) | ||
3203 | { | 3226 | { |
3204 | if (Int64.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture.NumberFormat, out var _)) | 3227 | return WixBundleVariableType.Version; |
3205 | { | 3228 | } |
3206 | newType = "numeric"; | 3229 | else if (Version.TryParse(value.Substring(1), out var _)) |
3207 | } | 3230 | { |
3208 | else | 3231 | return WixBundleVariableType.Version; |
3209 | { | ||
3210 | newType = "string"; | ||
3211 | } | ||
3212 | } | 3232 | } |
3213 | } | 3233 | } |
3214 | 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 _)) | ||
3216 | { | 3237 | { |
3217 | this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, "Variable", "Value", "Type")); | 3238 | return WixBundleVariableType.Numeric; |
3218 | } | 3239 | } |
3219 | 3240 | ||
3220 | return newType; | 3241 | return WixBundleVariableType.String; |
3221 | } | 3242 | } |
3222 | 3243 | ||
3223 | private class RemotePayload | 3244 | private class RemotePayload |
diff --git a/src/test/WixToolsetTest.CoreIntegration/BadInputFixture.cs b/src/test/WixToolsetTest.CoreIntegration/BadInputFixture.cs index d6c7b091..7a630a36 100644 --- a/src/test/WixToolsetTest.CoreIntegration/BadInputFixture.cs +++ b/src/test/WixToolsetTest.CoreIntegration/BadInputFixture.cs | |||
@@ -32,5 +32,28 @@ namespace WixToolsetTest.CoreIntegration | |||
32 | Assert.InRange(result.ExitCode, 2, Int32.MaxValue); | 32 | Assert.InRange(result.ExitCode, 2, Int32.MaxValue); |
33 | } | 33 | } |
34 | } | 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 | } | ||
35 | } | 58 | } |
36 | } | 59 | } |
diff --git a/src/test/WixToolsetTest.CoreIntegration/TestData/BadInput/BundleVariable.wxs b/src/test/WixToolsetTest.CoreIntegration/TestData/BadInput/BundleVariable.wxs new file mode 100644 index 00000000..293b379f --- /dev/null +++ b/src/test/WixToolsetTest.CoreIntegration/TestData/BadInput/BundleVariable.wxs | |||
@@ -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> | ||
diff --git a/src/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj b/src/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj index 601a66e7..f4aab391 100644 --- a/src/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj +++ b/src/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj | |||
@@ -22,6 +22,7 @@ | |||
22 | <Content Include="TestData\AppSearch\NestedDirSearchUnderRegSearch.msi" CopyToOutputDirectory="PreserveNewest" /> | 22 | <Content Include="TestData\AppSearch\NestedDirSearchUnderRegSearch.msi" CopyToOutputDirectory="PreserveNewest" /> |
23 | <Content Include="TestData\AppSearch\RegistrySearch.wxs" CopyToOutputDirectory="PreserveNewest" /> | 23 | <Content Include="TestData\AppSearch\RegistrySearch.wxs" CopyToOutputDirectory="PreserveNewest" /> |
24 | <Content Include="TestData\BadEnsureTable\BadEnsureTable.wxs" CopyToOutputDirectory="PreserveNewest" /> | 24 | <Content Include="TestData\BadEnsureTable\BadEnsureTable.wxs" CopyToOutputDirectory="PreserveNewest" /> |
25 | <Content Include="TestData\BadInput\BundleVariable.wxs" CopyToOutputDirectory="PreserveNewest" /> | ||
25 | <Content Include="TestData\BadInput\RegistryKey.wxs" CopyToOutputDirectory="PreserveNewest" /> | 26 | <Content Include="TestData\BadInput\RegistryKey.wxs" CopyToOutputDirectory="PreserveNewest" /> |
26 | <Content Include="TestData\BindVariables\DefaultedVariable.wxs" CopyToOutputDirectory="PreserveNewest" /> | 27 | <Content Include="TestData\BindVariables\DefaultedVariable.wxs" CopyToOutputDirectory="PreserveNewest" /> |
27 | <Content Include="TestData\BindVariables\data\test.txt" CopyToOutputDirectory="PreserveNewest" /> | 28 | <Content Include="TestData\BindVariables\data\test.txt" CopyToOutputDirectory="PreserveNewest" /> |