aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2022-07-07 12:32:55 -0700
committerRob Mensching <rob@firegiant.com>2022-07-07 15:12:11 -0700
commit76709e28e052c0b9708495153ddfd5303dc6623f (patch)
tree1885202cdb8214e2b7c6cdb602daa2d0a3ffb7c4
parenta08a76a4e7b9992fe05d4d8735beffad5bab54c6 (diff)
downloadwix-76709e28e052c0b9708495153ddfd5303dc6623f.tar.gz
wix-76709e28e052c0b9708495153ddfd5303dc6623f.tar.bz2
wix-76709e28e052c0b9708495153ddfd5303dc6623f.zip
Enable parsing invalid WixVersions
Fixes 6775
-rw-r--r--src/api/wix/WixToolset.Data/WixVersion.cs49
-rw-r--r--src/api/wix/test/WixToolsetTest.Data/WixVerFixture.cs194
2 files changed, 214 insertions, 29 deletions
diff --git a/src/api/wix/WixToolset.Data/WixVersion.cs b/src/api/wix/WixToolset.Data/WixVersion.cs
index ab68b55a..a0de7a10 100644
--- a/src/api/wix/WixToolset.Data/WixVersion.cs
+++ b/src/api/wix/WixToolset.Data/WixVersion.cs
@@ -40,6 +40,11 @@ namespace WixToolset.Data
40 public uint Revision { get; set; } 40 public uint Revision { get; set; }
41 41
42 /// <summary> 42 /// <summary>
43 /// Gets or sets whether the version did not parse correctly.
44 /// </summary>
45 public bool Invalid { get; set; }
46
47 /// <summary>
43 /// Gets or sets whether the major version was defined. 48 /// Gets or sets whether the major version was defined.
44 /// </summary> 49 /// </summary>
45 public bool HasMajor { get; set; } 50 public bool HasMajor { get; set; }
@@ -70,14 +75,13 @@ namespace WixToolset.Data
70 public string Metadata { get; set; } 75 public string Metadata { get; set; }
71 76
72 /// <summary> 77 /// <summary>
73 /// Tries to parse a string value into a valid <c>WixVersion</c>. 78 /// Parse a string value into a <c>WixVersion</c>. The returned version may be invalid.
74 /// </summary> 79 /// </summary>
75 /// <param name="parse">String value to parse into a version.</param> 80 /// <param name="parse">String value to parse into a version.</param>
76 /// <param name="version">Parsed version.</param> 81 /// <returns>Parsed version.</returns>
77 /// <returns>True if the version was successfully parsed, or false otherwise.</returns> 82 public static WixVersion Parse(string parse)
78 public static bool TryParse(string parse, out WixVersion version)
79 { 83 {
80 version = new WixVersion(); 84 var version = new WixVersion();
81 85
82 var labels = new List<WixVersionLabel>(); 86 var labels = new List<WixVersionLabel>();
83 var start = 0; 87 var start = 0;
@@ -286,14 +290,45 @@ namespace WixToolset.Data
286 } 290 }
287 } 291 }
288 292
293 version.Labels = labels.Count == 0 ? null : labels.ToArray();
294
289 if (invalid) 295 if (invalid)
290 { 296 {
297 // If the prefix was parsed but the rest of the version was
298 // invalid, store the full invalid version in the Metadata
299 // and clear the prefix.
300 if (version.Prefix.HasValue && partBegin == 1)
301 {
302 version.Prefix = null;
303 version.Metadata = parse;
304 }
305 else // store the remaining invalid content in Metadata.
306 {
307 version.Metadata = (partBegin < end) ? parse.Substring(partBegin) : String.Empty;
308 }
309
310 version.Invalid = true;
311 }
312
313 return version;
314 }
315
316 /// <summary>
317 /// Tries to parse a string value into a valid <c>WixVersion</c>.
318 /// </summary>
319 /// <param name="parse">String value to parse into a version.</param>
320 /// <param name="version">Parsed version.</param>
321 /// <returns>True if the version was successfully parsed, or false otherwise.</returns>
322 public static bool TryParse(string parse, out WixVersion version)
323 {
324 version = WixVersion.Parse(parse);
325
326 if (version.Invalid)
327 {
291 version = null; 328 version = null;
292 return false; 329 return false;
293 } 330 }
294 331
295 version.Labels = labels.Count == 0 ? null : labels.ToArray();
296
297 return true; 332 return true;
298 } 333 }
299 } 334 }
diff --git a/src/api/wix/test/WixToolsetTest.Data/WixVerFixture.cs b/src/api/wix/test/WixToolsetTest.Data/WixVerFixture.cs
index ffa3213a..56c72896 100644
--- a/src/api/wix/test/WixToolsetTest.Data/WixVerFixture.cs
+++ b/src/api/wix/test/WixToolsetTest.Data/WixVerFixture.cs
@@ -3,6 +3,7 @@
3namespace WixToolsetTest.Data 3namespace WixToolsetTest.Data
4{ 4{
5 using System; 5 using System;
6 using System.Linq;
6 using WixToolset.Data; 7 using WixToolset.Data;
7 using Xunit; 8 using Xunit;
8 9
@@ -16,6 +17,14 @@ namespace WixToolsetTest.Data
16 } 17 }
17 18
18 [Fact] 19 [Fact]
20 public void CanParseEmptyStringAsInvalidVersion()
21 {
22 var version = WixVersion.Parse(String.Empty);
23 Assert.Empty(version.Metadata);
24 Assert.True(version.Invalid);
25 }
26
27 [Fact]
19 public void CannotParseInvalidStringAsVersion() 28 public void CannotParseInvalidStringAsVersion()
20 { 29 {
21 Assert.False(WixVersion.TryParse("invalid", out var version)); 30 Assert.False(WixVersion.TryParse("invalid", out var version));
@@ -23,6 +32,14 @@ namespace WixToolsetTest.Data
23 } 32 }
24 33
25 [Fact] 34 [Fact]
35 public void CanParseInvalidStringAsInvalidVersion()
36 {
37 var version = WixVersion.Parse("invalid");
38 Assert.Equal("invalid", version.Metadata);
39 Assert.True(version.Invalid);
40 }
41
42 [Fact]
26 public void CanParseFourPartVersion() 43 public void CanParseFourPartVersion()
27 { 44 {
28 Assert.True(WixVersion.TryParse("1.2.3.4", out var version)); 45 Assert.True(WixVersion.TryParse("1.2.3.4", out var version));
@@ -37,6 +54,7 @@ namespace WixToolsetTest.Data
37 Assert.True(version.HasRevision); 54 Assert.True(version.HasRevision);
38 Assert.Null(version.Labels); 55 Assert.Null(version.Labels);
39 Assert.Null(version.Metadata); 56 Assert.Null(version.Metadata);
57 Assert.False(version.Invalid);
40 } 58 }
41 59
42 [Fact] 60 [Fact]
@@ -54,6 +72,7 @@ namespace WixToolsetTest.Data
54 Assert.False(version.HasRevision); 72 Assert.False(version.HasRevision);
55 Assert.Null(version.Labels); 73 Assert.Null(version.Labels);
56 Assert.Null(version.Metadata); 74 Assert.Null(version.Metadata);
75 Assert.False(version.Invalid);
57 } 76 }
58 77
59 [Fact] 78 [Fact]
@@ -71,6 +90,7 @@ namespace WixToolsetTest.Data
71 Assert.True(version.HasRevision); 90 Assert.True(version.HasRevision);
72 Assert.Null(version.Labels); 91 Assert.Null(version.Labels);
73 Assert.Null(version.Metadata); 92 Assert.Null(version.Metadata);
93 Assert.False(version.Invalid);
74 } 94 }
75 95
76 [Fact] 96 [Fact]
@@ -86,9 +106,10 @@ namespace WixToolsetTest.Data
86 Assert.True(version.HasMinor); 106 Assert.True(version.HasMinor);
87 Assert.False(version.HasPatch); 107 Assert.False(version.HasPatch);
88 Assert.False(version.HasRevision); 108 Assert.False(version.HasRevision);
89 Assert.Equal("19", version.Labels[0].Label); 109 Assert.Equal(new[] { "19" }, version.Labels.Select(l => l.Label).ToArray());
90 Assert.Equal((uint)19, version.Labels[0].Numeric); 110 Assert.Equal(new uint?[] { 19 }, version.Labels.Select(l => l.Numeric).ToArray());
91 Assert.Null(version.Metadata); 111 Assert.Null(version.Metadata);
112 Assert.False(version.Invalid);
92 } 113 }
93 114
94 [Fact] 115 [Fact]
@@ -104,11 +125,10 @@ namespace WixToolsetTest.Data
104 Assert.True(version.HasMinor); 125 Assert.True(version.HasMinor);
105 Assert.False(version.HasPatch); 126 Assert.False(version.HasPatch);
106 Assert.False(version.HasRevision); 127 Assert.False(version.HasRevision);
107 Assert.Equal("2", version.Labels[0].Label); 128 Assert.Equal(new[] { "2", "0" }, version.Labels.Select(l => l.Label).ToArray());
108 Assert.Equal((uint)2, version.Labels[0].Numeric); 129 Assert.Equal(new uint?[] { 2, 0 }, version.Labels.Select(l => l.Numeric).ToArray());
109 Assert.Equal("0", version.Labels[1].Label);
110 Assert.Equal((uint)0, version.Labels[1].Numeric);
111 Assert.Null(version.Metadata); 130 Assert.Null(version.Metadata);
131 Assert.False(version.Invalid);
112 } 132 }
113 133
114 [Fact] 134 [Fact]
@@ -124,9 +144,10 @@ namespace WixToolsetTest.Data
124 Assert.True(version.HasMinor); 144 Assert.True(version.HasMinor);
125 Assert.True(version.HasPatch); 145 Assert.True(version.HasPatch);
126 Assert.False(version.HasRevision); 146 Assert.False(version.HasRevision);
127 Assert.Equal("a", version.Labels[0].Label); 147 Assert.Equal(new[] { "a" }, version.Labels.Select(l => l.Label).ToArray());
128 Assert.Null(version.Labels[0].Numeric); 148 Assert.Equal(new uint?[] { null }, version.Labels.Select(l => l.Numeric).ToArray());
129 Assert.Null(version.Metadata); 149 Assert.Null(version.Metadata);
150 Assert.False(version.Invalid);
130 } 151 }
131 152
132 [Fact] 153 [Fact]
@@ -142,11 +163,10 @@ namespace WixToolsetTest.Data
142 Assert.True(version.HasMinor); 163 Assert.True(version.HasMinor);
143 Assert.False(version.HasPatch); 164 Assert.False(version.HasPatch);
144 Assert.False(version.HasRevision); 165 Assert.False(version.HasRevision);
145 Assert.Equal("a", version.Labels[0].Label); 166 Assert.Equal(new[] { "a", "000" }, version.Labels.Select(l => l.Label).ToArray());
146 Assert.Null(version.Labels[0].Numeric); 167 Assert.Equal(new uint?[] { null, 0 }, version.Labels.Select(l => l.Numeric).ToArray());
147 Assert.Equal("000", version.Labels[1].Label);
148 Assert.Equal((uint)0, version.Labels[1].Numeric);
149 Assert.Null(version.Metadata); 168 Assert.Null(version.Metadata);
169 Assert.False(version.Invalid);
150 } 170 }
151 171
152 [Fact] 172 [Fact]
@@ -164,6 +184,7 @@ namespace WixToolsetTest.Data
164 Assert.False(version.HasRevision); 184 Assert.False(version.HasRevision);
165 Assert.Null(version.Labels); 185 Assert.Null(version.Labels);
166 Assert.Equal("abcd", version.Metadata); 186 Assert.Equal("abcd", version.Metadata);
187 Assert.False(version.Invalid);
167 } 188 }
168 189
169 [Fact] 190 [Fact]
@@ -176,6 +197,18 @@ namespace WixToolsetTest.Data
176 } 197 }
177 198
178 [Fact] 199 [Fact]
200 public void CanParseUnexpectedContentAsInvalidMetadata()
201 {
202 var version = WixVersion.Parse("1.2.3.abcd");
203 Assert.Equal("abcd", version.Metadata);
204 Assert.True(version.Invalid);
205
206 version = WixVersion.Parse("1.2.3.-abcd");
207 Assert.Equal("-abcd", version.Metadata);
208 Assert.True(version.Invalid);
209 }
210
211 [Fact]
179 public void CanParseLeadingPrefix() 212 public void CanParseLeadingPrefix()
180 { 213 {
181 Assert.True(WixVersion.TryParse("v10.20.30.40", out var version)); 214 Assert.True(WixVersion.TryParse("v10.20.30.40", out var version));
@@ -190,6 +223,7 @@ namespace WixToolsetTest.Data
190 Assert.True(version.HasRevision); 223 Assert.True(version.HasRevision);
191 Assert.Null(version.Labels); 224 Assert.Null(version.Labels);
192 Assert.Null(version.Metadata); 225 Assert.Null(version.Metadata);
226 Assert.False(version.Invalid);
193 227
194 Assert.True(WixVersion.TryParse("V100.200.300.400", out var version2)); 228 Assert.True(WixVersion.TryParse("V100.200.300.400", out var version2));
195 Assert.Equal('V', version2.Prefix); 229 Assert.Equal('V', version2.Prefix);
@@ -203,6 +237,7 @@ namespace WixToolsetTest.Data
203 Assert.True(version.HasRevision); 237 Assert.True(version.HasRevision);
204 Assert.Null(version2.Labels); 238 Assert.Null(version2.Labels);
205 Assert.Null(version2.Metadata); 239 Assert.Null(version2.Metadata);
240 Assert.False(version.Invalid);
206 } 241 }
207 242
208 [Fact] 243 [Fact]
@@ -220,6 +255,7 @@ namespace WixToolsetTest.Data
220 Assert.True(version.HasRevision); 255 Assert.True(version.HasRevision);
221 Assert.Null(version.Labels); 256 Assert.Null(version.Labels);
222 Assert.Null(version.Metadata); 257 Assert.Null(version.Metadata);
258 Assert.False(version.Invalid);
223 } 259 }
224 260
225 [Fact] 261 [Fact]
@@ -230,6 +266,24 @@ namespace WixToolsetTest.Data
230 } 266 }
231 267
232 [Fact] 268 [Fact]
269 public void CanParseInvalidTooLargeNumbers()
270 {
271 var version = WixVersion.Parse("4294967296.4294967296.4294967296.4294967296");
272 Assert.Equal(0U, version.Major);
273 Assert.Equal("4294967296.4294967296.4294967296.4294967296", version.Metadata);
274 Assert.True(version.Invalid);
275 }
276
277 [Fact]
278 public void CanParseInvalidTooLargeNumbersWithPrefix()
279 {
280 var version = WixVersion.Parse("v4294967296.4294967296.4294967296.4294967296");
281 Assert.Equal("v4294967296.4294967296.4294967296.4294967296", version.Metadata);
282 Assert.Null(version.Prefix);
283 Assert.True(version.Invalid);
284 }
285
286 [Fact]
233 public void CanParseLabelsWithMetadata() 287 public void CanParseLabelsWithMetadata()
234 { 288 {
235 Assert.True(WixVersion.TryParse("1.2.3.4-a.b.c.d.5+abc123", out var version)); 289 Assert.True(WixVersion.TryParse("1.2.3.4-a.b.c.d.5+abc123", out var version));
@@ -242,17 +296,113 @@ namespace WixToolsetTest.Data
242 Assert.True(version.HasMinor); 296 Assert.True(version.HasMinor);
243 Assert.True(version.HasPatch); 297 Assert.True(version.HasPatch);
244 Assert.True(version.HasRevision); 298 Assert.True(version.HasRevision);
245 Assert.Equal("a", version.Labels[0].Label); 299 Assert.Equal(new[] { "a", "b", "c", "d", "5" }, version.Labels.Select(l => l.Label).ToArray());
246 Assert.Null(version.Labels[0].Numeric); 300 Assert.Equal(new uint?[] { null, null, null, null, 5 }, version.Labels.Select(l => l.Numeric).ToArray());
247 Assert.Equal("b", version.Labels[1].Label);
248 Assert.Null(version.Labels[1].Numeric);
249 Assert.Equal("c", version.Labels[2].Label);
250 Assert.Null(version.Labels[2].Numeric);
251 Assert.Equal("d", version.Labels[3].Label);
252 Assert.Null(version.Labels[3].Numeric);
253 Assert.Equal("5", version.Labels[4].Label);
254 Assert.Equal((uint)5, version.Labels[4].Numeric);
255 Assert.Equal("abc123", version.Metadata); 301 Assert.Equal("abc123", version.Metadata);
302 Assert.False(version.Invalid);
303 }
304
305 [Fact]
306 public void CanParseVersionWithTrailingDotsAsInvalid()
307 {
308 var version = WixVersion.Parse(".");
309 Assert.Null(version.Prefix);
310 Assert.Equal(0U, version.Major);
311 Assert.Equal(0U, version.Minor);
312 Assert.Equal(0U, version.Patch);
313 Assert.Equal(0U, version.Revision);
314 Assert.Null(version.Labels);
315 Assert.False(version.HasMajor);
316 Assert.False(version.HasMinor);
317 Assert.False(version.HasPatch);
318 Assert.False(version.HasRevision);
319 Assert.Equal(".", version.Metadata);
320 Assert.True(version.Invalid);
321
322 version = WixVersion.Parse("1.");
323 Assert.Null(version.Prefix);
324 Assert.Equal(1U, version.Major);
325 Assert.Equal(0U, version.Minor);
326 Assert.Equal(0U, version.Patch);
327 Assert.Equal(0U, version.Revision);
328 Assert.Null(version.Labels);
329 Assert.True(version.HasMajor);
330 Assert.False(version.HasMinor);
331 Assert.False(version.HasPatch);
332 Assert.False(version.HasRevision);
333 Assert.Equal(String.Empty, version.Metadata);
334 Assert.True(version.Invalid);
335
336 version = WixVersion.Parse("2.1.");
337 Assert.Null(version.Prefix);
338 Assert.Equal(2U, version.Major);
339 Assert.Equal(1U, version.Minor);
340 Assert.Equal(0U, version.Patch);
341 Assert.Equal(0U, version.Revision);
342 Assert.Null(version.Labels);
343 Assert.True(version.HasMajor);
344 Assert.True(version.HasMinor);
345 Assert.False(version.HasPatch);
346 Assert.False(version.HasRevision);
347 Assert.Equal(String.Empty, version.Metadata);
348 Assert.True(version.Invalid);
349
350 version = WixVersion.Parse("3.2.1.");
351 Assert.Null(version.Prefix);
352 Assert.Equal(3U, version.Major);
353 Assert.Equal(2U, version.Minor);
354 Assert.Equal(1U, version.Patch);
355 Assert.Equal(0U, version.Revision);
356 Assert.Null(version.Labels);
357 Assert.True(version.HasMajor);
358 Assert.True(version.HasMinor);
359 Assert.True(version.HasPatch);
360 Assert.False(version.HasRevision);
361 Assert.Equal(String.Empty, version.Metadata);
362 Assert.True(version.Invalid);
363
364 version = WixVersion.Parse("4.3.2.1.");
365 Assert.Null(version.Prefix);
366 Assert.Equal(4U, version.Major);
367 Assert.Equal(3U, version.Minor);
368 Assert.Equal(2U, version.Patch);
369 Assert.Equal(1U, version.Revision);
370 Assert.Null(version.Labels);
371 Assert.True(version.HasMajor);
372 Assert.True(version.HasMinor);
373 Assert.True(version.HasPatch);
374 Assert.True(version.HasRevision);
375 Assert.Equal(String.Empty, version.Metadata);
376 Assert.True(version.Invalid);
377
378 version = WixVersion.Parse("5-.");
379 Assert.Null(version.Prefix);
380 Assert.Equal(5U, version.Major);
381 Assert.Equal(0U, version.Minor);
382 Assert.Equal(0U, version.Patch);
383 Assert.Equal(0U, version.Revision);
384 Assert.Null(version.Labels);
385 Assert.True(version.HasMajor);
386 Assert.False(version.HasMinor);
387 Assert.False(version.HasPatch);
388 Assert.False(version.HasRevision);
389 Assert.Equal(".", version.Metadata);
390 Assert.True(version.Invalid);
391
392 version = WixVersion.Parse("6-a.");
393 Assert.Null(version.Prefix);
394 Assert.Equal(6U, version.Major);
395 Assert.Equal(0U, version.Minor);
396 Assert.Equal(0U, version.Patch);
397 Assert.Equal(0U, version.Revision);
398 Assert.Equal(new[] { "a" }, version.Labels.Select(l => l.Label).ToArray());
399 Assert.Equal(new uint?[] { null }, version.Labels.Select(l => l.Numeric).ToArray());
400 Assert.True(version.HasMajor);
401 Assert.False(version.HasMinor);
402 Assert.False(version.HasPatch);
403 Assert.False(version.HasRevision);
404 Assert.Equal(String.Empty, version.Metadata);
405 Assert.True(version.Invalid);
256 } 406 }
257 } 407 }
258} 408}