@joebigelow / wix-1 / commits / 0ea53e27

Store the prefix character in VERUTIL_VERSION.

Fix edge case where version string is all v's.

Sean Hall committed May 16, 2022 at 16:03 UTC 0ea53e27361cbfe664df98d717e55005f329aff1
7 files changed +118 -14
src/api/burn/WixToolset.Mba.Core/VerUtil.cs
+1
@@ -59,6 +59,7 @@ namespace WixToolset.Mba.Core
59 internal struct VersionStruct
60 {
61 public IntPtr sczVersion;
62 + public char chPrefix;
63 public uint dwMajor;
64 public uint dwMinor;
65 public uint dwPatch;
src/api/burn/WixToolset.Mba.Core/VerUtilVersion.cs
+6
@@ -17,6 +17,7 @@ namespace WixToolset.Mba.Core
17 var pVersion = handle.DangerousGetHandle();
18 var version = (VerUtil.VersionStruct)Marshal.PtrToStructure(pVersion, typeof(VerUtil.VersionStruct));
19 this.Version = Marshal.PtrToStringUni(version.sczVersion);
20 + this.Prefix = version.chPrefix;
21 this.Major = version.dwMajor;
22 this.Minor = version.dwMinor;
23 this.Patch = version.dwPatch;
@@ -38,6 +39,11 @@ namespace WixToolset.Mba.Core
39 /// </summary>
40 public string Version { get; private set; }
41
42 + /// <summary>
43 + /// Prefix character that was stripped from <c>Version</c>, or the null character if there was no prefix.
44 + /// </summary>
45 + public char Prefix { get; private set; }
46 +
47 /// <summary>
48 /// For version A.B.C.D, Major is A. It is 0 if not specified.
49 /// </summary>
src/api/burn/test/WixToolsetTest.Mba.Core/VerUtilFixture.cs
+2
@@ -49,6 +49,7 @@ namespace WixToolsetTest.Mba.Core
49
50 using var parsedVersion = VerUtil.VersionFromQword(qwVersion);
51 Assert.Equal("100.200.300.400", parsedVersion.Version);
52 + Assert.Equal('\0', parsedVersion.Prefix);
53 Assert.Equal(100u, parsedVersion.Major);
54 Assert.Equal(200u, parsedVersion.Minor);
55 Assert.Equal(300u, parsedVersion.Patch);
@@ -65,6 +66,7 @@ namespace WixToolsetTest.Mba.Core
66
67 using var parsedVersion = VerUtil.ParseVersion(version, strict: false);
68 Assert.Equal(version, parsedVersion.Version);
69 + Assert.Equal('\0', parsedVersion.Prefix);
70 Assert.Equal(1u, parsedVersion.Major);
71 Assert.Equal(2u, parsedVersion.Minor);
72 Assert.Equal(3u, parsedVersion.Patch);
src/burn/test/BurnUnitTest/RegistrationTest.cpp
+3
@@ -559,6 +559,7 @@ namespace Bootstrapper
559 L" <Variable Id='MyBurnVariable2' Type='string' Value='foo' Hidden='no' Persisted='yes' />"
560 L" <Variable Id='MyBurnVariable3' Type='version' Value='v1.1-alpha' Hidden='no' Persisted='yes' />"
561 L" <Variable Id='MyBurnVariable4' Type='string' Value='foo' Hidden='no' Persisted='no' />"
562 + L" <Variable Id='MyBurnVariable5' Type='version' Hidden='no' Persisted='yes' />"
563 L" <CommandLine Variables='upperCase' />"
564 L"</Bundle>";
565
@@ -597,6 +598,7 @@ namespace Bootstrapper
598 VariableSetNumericHelper(&variables, L"MyBurnVariable1", 42);
599 VariableSetStringHelper(&variables, L"MyBurnVariable2", L"bar", FALSE);
600 VariableSetVersionHelper(&variables, L"MyBurnVariable3", L"v1.0-beta");
601 + VariableSetVersionHelper(&variables, L"MyBurnVariable5", L"vvv");
602
603 hr = VariableSerialize(&variables, TRUE, &pbBuffer, &cbBuffer);
604 TestThrowOnFailure(hr, "Failed to serialize variables.");
@@ -616,6 +618,7 @@ namespace Bootstrapper
618 this->ValidateVariableKey(L"MyBurnVariable1", gcnew String(L"42"));
619 this->ValidateVariableKey(L"MyBurnVariable2", gcnew String(L"bar"));
620 this->ValidateVariableKey(L"MyBurnVariable3", gcnew String(L"1.0-beta"));
621 + this->ValidateVariableKey(L"MyBurnVariable5", gcnew String(L"vvv"));
622 this->ValidateVariableKeyEmpty(L"WixBundleForcedRestartPackage");
623
624 hr = StrAlloc(&sczRelatedBundleId, MAX_GUID_CHARS + 1);
src/libs/dutil/WixToolset.DUtil/inc/verutil.h
+1
@@ -19,6 +19,7 @@ typedef struct _VERUTIL_VERSION_RELEASE_LABEL
19 typedef struct _VERUTIL_VERSION
20 {
21 LPWSTR sczVersion;
22 + WCHAR chPrefix;
23 DWORD dwMajor;
24 DWORD dwMinor;
25 DWORD dwPatch;
src/libs/dutil/WixToolset.DUtil/verutil.cpp
+25 -12
@@ -194,6 +194,7 @@ DAPI_(HRESULT) VerCopyVersion(
194 hr = StrAllocString(&pCopy->sczVersion, pSource->sczVersion, 0);
195 VerExitOnFailure(hr, "Failed to copy Verutil version string '%ls'.", pSource->sczVersion);
196
197 + pCopy->chPrefix = pSource->chPrefix;
198 pCopy->dwMajor = pSource->dwMajor;
199 pCopy->dwMinor = pSource->dwMinor;
200 pCopy->dwPatch = pSource->dwPatch;
@@ -251,6 +252,7 @@ DAPI_(HRESULT) VerParseVersion(
252 {
253 HRESULT hr = S_OK;
254 VERUTIL_VERSION* pVersion = NULL;
255 + LPCWSTR wzString = NULL;
256 LPCWSTR wzEnd = NULL;
257 LPCWSTR wzPartBegin = NULL;
258 LPCWSTR wzPartEnd = NULL;
@@ -277,22 +279,22 @@ DAPI_(HRESULT) VerParseVersion(
279 VerExitOnRootFailure(hr = E_INVALIDARG, "Version string is too long: %Iu", cchVersion);
280 }
281
280 - if (L'v' == *wzVersion || L'V' == *wzVersion)
281 - {
282 - ++wzVersion;
283 - --cchVersion;
284 - }
285 -
282 pVersion = reinterpret_cast<VERUTIL_VERSION*>(MemAlloc(sizeof(VERUTIL_VERSION), TRUE));
283 VerExitOnNull(pVersion, hr, E_OUTOFMEMORY, "Failed to allocate memory for Verutil version '%ls'.", wzVersion);
284
289 - hr = StrAllocString(&pVersion->sczVersion, wzVersion, cchVersion);
290 - VerExitOnFailure(hr, "Failed to copy Verutil version string '%ls'.", wzVersion);
285 + wzString = wzVersion;
286 +
287 + if (L'v' == *wzString || L'V' == *wzString)
288 + {
289 + pVersion->chPrefix = *wzString;
290 + ++wzString;
291 + --cchVersion;
292 + }
293
292 - wzVersion = wzPartBegin = wzPartEnd = pVersion->sczVersion;
294 + wzPartBegin = wzPartEnd = wzString;
295
296 // Save end pointer.
295 - wzEnd = wzVersion + cchVersion;
297 + wzEnd = wzString + cchVersion;
298
299 // Parse version number
300 while (wzPartBegin < wzEnd)
@@ -473,7 +475,7 @@ DAPI_(HRESULT) VerParseVersion(
475 pReleaseLabel->dwValue = uLabel;
476 }
477
476 - pReleaseLabel->cchLabelOffset = wzPartBegin - pVersion->sczVersion;
478 + pReleaseLabel->cchLabelOffset = wzPartBegin - wzString;
479 pReleaseLabel->cchLabel = cchLabel;
480
481 if (fTrailingDot)
@@ -507,9 +509,20 @@ DAPI_(HRESULT) VerParseVersion(
509 ExitFunction1(hr = E_INVALIDARG);
510 }
511
510 - pVersion->cchMetadataOffset = min(wzPartBegin, wzEnd) - pVersion->sczVersion;
512 + pVersion->cchMetadataOffset = min(wzPartBegin, wzEnd) - wzString;
513 pVersion->fInvalid = fInvalid;
514
515 + // If the whole string was invalid, then don't clip off the prefix.
516 + if (!pVersion->cchMetadataOffset && pVersion->chPrefix)
517 + {
518 + pVersion->chPrefix = '\0';
519 + wzString = wzVersion;
520 + ++cchVersion;
521 + }
522 +
523 + hr = StrAllocString(&pVersion->sczVersion, wzString, cchVersion);
524 + VerExitOnFailure(hr, "Failed to copy Verutil version string '%ls'.", wzVersion);
525 +
526 *ppVersion = pVersion;
527 pVersion = NULL;
528 hr = S_OK;
src/libs/dutil/test/DUtilUnitTest/VerUtilTests.cpp
+80 -2
@@ -34,6 +34,7 @@ namespace DutilTests
34 NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion3);
35
36 NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion);
37 + Assert::Equal<WCHAR>(L'\0', pVersion1->chPrefix);
38 Assert::Equal<DWORD>(1, pVersion1->dwMajor);
39 Assert::Equal<DWORD>(2, pVersion1->dwMinor);
40 Assert::Equal<DWORD>(3, pVersion1->dwPatch);
@@ -43,6 +44,7 @@ namespace DutilTests
44 Assert::Equal<BOOL>(FALSE, pVersion1->fInvalid);
45
46 NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion);
47 + Assert::Equal<WCHAR>(L'\0', pVersion2->chPrefix);
48 Assert::Equal<DWORD>(1, pVersion2->dwMajor);
49 Assert::Equal<DWORD>(2, pVersion2->dwMinor);
50 Assert::Equal<DWORD>(3, pVersion2->dwPatch);
@@ -52,6 +54,7 @@ namespace DutilTests
54 Assert::Equal<BOOL>(FALSE, pVersion2->fInvalid);
55
56 NativeAssert::StringEqual(wzVersion3, pVersion3->sczVersion);
57 + Assert::Equal<WCHAR>(L'\0', pVersion3->chPrefix);
58 Assert::Equal<DWORD>(1, pVersion3->dwMajor);
59 Assert::Equal<DWORD>(2, pVersion3->dwMinor);
60 Assert::Equal<DWORD>(3, pVersion3->dwPatch);
@@ -89,6 +92,7 @@ namespace DutilTests
92 NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion2);
93
94 NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion);
95 + Assert::Equal<WCHAR>(L'\0', pVersion1->chPrefix);
96 Assert::Equal<DWORD>(1, pVersion1->dwMajor);
97 Assert::Equal<DWORD>(0, pVersion1->dwMinor);
98 Assert::Equal<DWORD>(0, pVersion1->dwPatch);
@@ -109,6 +113,7 @@ namespace DutilTests
113 Assert::Equal<BOOL>(FALSE, pVersion1->fInvalid);
114
115 NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion);
116 + Assert::Equal<WCHAR>(L'\0', pVersion2->chPrefix);
117 Assert::Equal<DWORD>(1, pVersion2->dwMajor);
118 Assert::Equal<DWORD>(0, pVersion2->dwMinor);
119 Assert::Equal<DWORD>(0, pVersion2->dwPatch);
@@ -170,6 +175,7 @@ namespace DutilTests
175 NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion6);
176
177 NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion);
178 + Assert::Equal<WCHAR>(L'\0', pVersion1->chPrefix);
179 Assert::Equal<DWORD>(10, pVersion1->dwMajor);
180 Assert::Equal<DWORD>(0, pVersion1->dwMinor);
181 Assert::Equal<DWORD>(0, pVersion1->dwPatch);
@@ -179,6 +185,7 @@ namespace DutilTests
185 Assert::Equal<BOOL>(TRUE, pVersion1->fInvalid);
186
187 NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion);
188 + Assert::Equal<WCHAR>(L'\0', pVersion2->chPrefix);
189 Assert::Equal<DWORD>(10, pVersion2->dwMajor);
190 Assert::Equal<DWORD>(0, pVersion2->dwMinor);
191 Assert::Equal<DWORD>(0, pVersion2->dwPatch);
@@ -188,6 +195,7 @@ namespace DutilTests
195 Assert::Equal<BOOL>(TRUE, pVersion2->fInvalid);
196
197 NativeAssert::StringEqual(wzVersion3, pVersion3->sczVersion);
198 + Assert::Equal<WCHAR>(L'\0', pVersion3->chPrefix);
199 Assert::Equal<DWORD>(0, pVersion3->dwMajor);
200 Assert::Equal<DWORD>(0, pVersion3->dwMinor);
201 Assert::Equal<DWORD>(0, pVersion3->dwPatch);
@@ -197,6 +205,7 @@ namespace DutilTests
205 Assert::Equal<BOOL>(FALSE, pVersion3->fInvalid);
206
207 NativeAssert::StringEqual(wzVersion4, pVersion4->sczVersion);
208 + Assert::Equal<WCHAR>(L'\0', pVersion4->chPrefix);
209 Assert::Equal<DWORD>(0, pVersion4->dwMajor);
210 Assert::Equal<DWORD>(0, pVersion4->dwMinor);
211 Assert::Equal<DWORD>(0, pVersion4->dwPatch);
@@ -206,6 +215,7 @@ namespace DutilTests
215 Assert::Equal<BOOL>(TRUE, pVersion4->fInvalid);
216
217 NativeAssert::StringEqual(wzVersion5, pVersion5->sczVersion);
218 + Assert::Equal<WCHAR>(L'\0', pVersion5->chPrefix);
219 Assert::Equal<DWORD>(10, pVersion5->dwMajor);
220 Assert::Equal<DWORD>(0, pVersion5->dwMinor);
221 Assert::Equal<DWORD>(0, pVersion5->dwPatch);
@@ -221,6 +231,7 @@ namespace DutilTests
231 Assert::Equal<BOOL>(FALSE, pVersion5->fInvalid);
232
233 NativeAssert::StringEqual(wzVersion6, pVersion6->sczVersion);
234 + Assert::Equal<WCHAR>(L'\0', pVersion6->chPrefix);
235 Assert::Equal<DWORD>(10, pVersion6->dwMajor);
236 Assert::Equal<DWORD>(0, pVersion6->dwMinor);
237 Assert::Equal<DWORD>(0, pVersion6->dwPatch);
@@ -273,6 +284,7 @@ namespace DutilTests
284 NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion3);
285
286 NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion);
287 + Assert::Equal<WCHAR>(L'\0', pVersion1->chPrefix);
288 Assert::Equal<DWORD>(0, pVersion1->dwMajor);
289 Assert::Equal<DWORD>(0, pVersion1->dwMinor);
290 Assert::Equal<DWORD>(1, pVersion1->dwPatch);
@@ -287,6 +299,7 @@ namespace DutilTests
299 Assert::Equal<BOOL>(FALSE, pVersion1->fInvalid);
300
301 NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion);
302 + Assert::Equal<WCHAR>(L'\0', pVersion2->chPrefix);
303 Assert::Equal<DWORD>(0, pVersion2->dwMajor);
304 Assert::Equal<DWORD>(0, pVersion2->dwMinor);
305 Assert::Equal<DWORD>(0, pVersion2->dwPatch);
@@ -302,6 +315,7 @@ namespace DutilTests
315 Assert::Equal<BOOL>(FALSE, pVersion2->fInvalid);
316
317 NativeAssert::StringEqual(wzVersion3, pVersion3->sczVersion);
318 + Assert::Equal<WCHAR>(L'\0', pVersion3->chPrefix);
319 Assert::Equal<DWORD>(1, pVersion3->dwMajor);
320 Assert::Equal<DWORD>(0, pVersion3->dwMinor);
321 Assert::Equal<DWORD>(0, pVersion3->dwPatch);
@@ -355,6 +369,7 @@ namespace DutilTests
369 NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion4);
370
371 NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion);
372 + Assert::Equal<WCHAR>(L'\0', pVersion1->chPrefix);
373 Assert::Equal<DWORD>(0, pVersion1->dwMajor);
374 Assert::Equal<DWORD>(1, pVersion1->dwMinor);
375 Assert::Equal<DWORD>(0, pVersion1->dwPatch);
@@ -374,6 +389,7 @@ namespace DutilTests
389 Assert::Equal<BOOL>(FALSE, pVersion1->fInvalid);
390
391 NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion);
392 + Assert::Equal<WCHAR>(L'\0', pVersion2->chPrefix);
393 Assert::Equal<DWORD>(0, pVersion2->dwMajor);
394 Assert::Equal<DWORD>(1, pVersion2->dwMinor);
395 Assert::Equal<DWORD>(0, pVersion2->dwPatch);
@@ -393,6 +409,7 @@ namespace DutilTests
409 Assert::Equal<BOOL>(FALSE, pVersion2->fInvalid);
410
411 NativeAssert::StringEqual(wzVersion3, pVersion3->sczVersion);
412 + Assert::Equal<WCHAR>(L'\0', pVersion3->chPrefix);
413 Assert::Equal<DWORD>(0, pVersion3->dwMajor);
414 Assert::Equal<DWORD>(1, pVersion3->dwMinor);
415 Assert::Equal<DWORD>(0, pVersion3->dwPatch);
@@ -416,6 +433,7 @@ namespace DutilTests
433 Assert::Equal<BOOL>(FALSE, pVersion3->fInvalid);
434
435 NativeAssert::StringEqual(wzVersion4, pVersion4->sczVersion);
436 + Assert::Equal<WCHAR>(L'\0', pVersion4->chPrefix);
437 Assert::Equal<DWORD>(0, pVersion4->dwMajor);
438 Assert::Equal<DWORD>(1, pVersion4->dwMinor);
439 Assert::Equal<DWORD>(0, pVersion4->dwPatch);
@@ -473,6 +491,7 @@ namespace DutilTests
491 NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion3);
492
493 NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion);
494 + Assert::Equal<WCHAR>(L'\0', pVersion1->chPrefix);
495 Assert::Equal<DWORD>(1, pVersion1->dwMajor);
496 Assert::Equal<DWORD>(2, pVersion1->dwMinor);
497 Assert::Equal<DWORD>(3, pVersion1->dwPatch);
@@ -482,6 +501,7 @@ namespace DutilTests
501 Assert::Equal<BOOL>(FALSE, pVersion1->fInvalid);
502
503 NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion);
504 + Assert::Equal<WCHAR>(L'\0', pVersion2->chPrefix);
505 Assert::Equal<DWORD>(1, pVersion2->dwMajor);
506 Assert::Equal<DWORD>(2, pVersion2->dwMinor);
507 Assert::Equal<DWORD>(3, pVersion2->dwPatch);
@@ -491,6 +511,7 @@ namespace DutilTests
511 Assert::Equal<BOOL>(TRUE, pVersion2->fInvalid);
512
513 NativeAssert::StringEqual(wzVersion3, pVersion3->sczVersion);
514 + Assert::Equal<WCHAR>(L'\0', pVersion3->chPrefix);
515 Assert::Equal<DWORD>(1, pVersion3->dwMajor);
516 Assert::Equal<DWORD>(2, pVersion3->dwMinor);
517 Assert::Equal<DWORD>(3, pVersion3->dwPatch);
@@ -518,9 +539,13 @@ namespace DutilTests
539 VERUTIL_VERSION* pVersion1 = NULL;
540 VERUTIL_VERSION* pVersion2 = NULL;
541 VERUTIL_VERSION* pVersion3 = NULL;
542 + VERUTIL_VERSION* pVersion4 = NULL;
543 + VERUTIL_VERSION* pVersion5 = NULL;
544 LPCWSTR wzVersion1 = L"10.20.30.40";
545 LPCWSTR wzVersion2 = L"v10.20.30.40";
546 LPCWSTR wzVersion3 = L"V10.20.30.40";
547 + LPCWSTR wzVersion4 = L"v10.20.30.40-abc";
548 + LPCWSTR wzVersion5 = L"vvv";
549
550 try
551 {
@@ -533,7 +558,14 @@ namespace DutilTests
558 hr = VerParseVersion(wzVersion3, 0, FALSE, &pVersion3);
559 NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion3);
560
561 + hr = VerParseVersion(wzVersion4, 0, FALSE, &pVersion4);
562 + NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion4);
563 +
564 + hr = VerParseVersion(wzVersion5, 0, FALSE, &pVersion5);
565 + NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion5);
566 +
567 NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion);
568 + Assert::Equal<WCHAR>(L'\0', pVersion1->chPrefix);
569 Assert::Equal<DWORD>(10, pVersion1->dwMajor);
570 Assert::Equal<DWORD>(20, pVersion1->dwMinor);
571 Assert::Equal<DWORD>(30, pVersion1->dwPatch);
@@ -543,6 +575,7 @@ namespace DutilTests
575 Assert::Equal<BOOL>(FALSE, pVersion1->fInvalid);
576
577 NativeAssert::StringEqual(wzVersion1, pVersion2->sczVersion);
578 + Assert::Equal<WCHAR>(L'v', pVersion2->chPrefix);
579 Assert::Equal<DWORD>(10, pVersion2->dwMajor);
580 Assert::Equal<DWORD>(20, pVersion2->dwMinor);
581 Assert::Equal<DWORD>(30, pVersion2->dwPatch);
@@ -552,6 +585,7 @@ namespace DutilTests
585 Assert::Equal<BOOL>(FALSE, pVersion2->fInvalid);
586
587 NativeAssert::StringEqual(wzVersion1, pVersion3->sczVersion);
588 + Assert::Equal<WCHAR>(L'V', pVersion3->chPrefix);
589 Assert::Equal<DWORD>(10, pVersion3->dwMajor);
590 Assert::Equal<DWORD>(20, pVersion3->dwMinor);
591 Assert::Equal<DWORD>(30, pVersion3->dwPatch);
@@ -560,14 +594,42 @@ namespace DutilTests
594 Assert::Equal<DWORD>(11, pVersion3->cchMetadataOffset);
595 Assert::Equal<BOOL>(FALSE, pVersion3->fInvalid);
596
597 + NativeAssert::StringEqual(L"10.20.30.40-abc", pVersion4->sczVersion);
598 + Assert::Equal<WCHAR>(L'v', pVersion4->chPrefix);
599 + Assert::Equal<DWORD>(10, pVersion4->dwMajor);
600 + Assert::Equal<DWORD>(20, pVersion4->dwMinor);
601 + Assert::Equal<DWORD>(30, pVersion4->dwPatch);
602 + Assert::Equal<DWORD>(40, pVersion4->dwRevision);
603 + Assert::Equal<DWORD>(1, pVersion4->cReleaseLabels);
604 +
605 + Assert::Equal<BOOL>(FALSE, pVersion4->rgReleaseLabels[0].fNumeric);
606 + Assert::Equal<DWORD>(3, pVersion4->rgReleaseLabels[0].cchLabel);
607 + Assert::Equal<DWORD>(12, pVersion4->rgReleaseLabels[0].cchLabelOffset);
608 +
609 + Assert::Equal<DWORD>(15, pVersion4->cchMetadataOffset);
610 + Assert::Equal<BOOL>(FALSE, pVersion4->fInvalid);
611 +
612 + NativeAssert::StringEqual(wzVersion5, pVersion5->sczVersion);
613 + Assert::Equal<WCHAR>(L'\0', pVersion5->chPrefix);
614 + Assert::Equal<DWORD>(0, pVersion5->dwMajor);
615 + Assert::Equal<DWORD>(0, pVersion5->dwMinor);
616 + Assert::Equal<DWORD>(0, pVersion5->dwPatch);
617 + Assert::Equal<DWORD>(0, pVersion5->dwRevision);
618 + Assert::Equal<DWORD>(0, pVersion5->cReleaseLabels);
619 + Assert::Equal<DWORD>(0, pVersion5->cchMetadataOffset);
620 + Assert::Equal<BOOL>(TRUE, pVersion5->fInvalid);
621 +
622 TestVerutilCompareParsedVersions(pVersion1, pVersion2, 0);
623 TestVerutilCompareParsedVersions(pVersion1, pVersion3, 0);
624 + TestVerutilCompareParsedVersions(pVersion1, pVersion4, 1);
625 }
626 finally
627 {
628 ReleaseVerutilVersion(pVersion1);
629 ReleaseVerutilVersion(pVersion2);
630 ReleaseVerutilVersion(pVersion3);
631 + ReleaseVerutilVersion(pVersion4);
632 + ReleaseVerutilVersion(pVersion5);
633 }
634 }
635
@@ -589,6 +651,7 @@ namespace DutilTests
651 NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion2);
652
653 NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion);
654 + Assert::Equal<WCHAR>(L'\0', pVersion1->chPrefix);
655 Assert::Equal<DWORD>(4294967295, pVersion1->dwMajor);
656 Assert::Equal<DWORD>(4294967295, pVersion1->dwMinor);
657 Assert::Equal<DWORD>(4294967295, pVersion1->dwPatch);
@@ -598,6 +661,7 @@ namespace DutilTests
661 Assert::Equal<BOOL>(FALSE, pVersion1->fInvalid);
662
663 NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion);
664 + Assert::Equal<WCHAR>(L'\0', pVersion2->chPrefix);
665 Assert::Equal<DWORD>(0, pVersion2->dwMajor);
666 Assert::Equal<DWORD>(0, pVersion2->dwMinor);
667 Assert::Equal<DWORD>(0, pVersion2->dwPatch);
@@ -633,6 +697,7 @@ namespace DutilTests
697 NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion2);
698
699 NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion);
700 + Assert::Equal<WCHAR>(L'\0', pVersion1->chPrefix);
701 Assert::Equal<DWORD>(1, pVersion1->dwMajor);
702 Assert::Equal<DWORD>(2, pVersion1->dwMinor);
703 Assert::Equal<DWORD>(3, pVersion1->dwPatch);
@@ -642,6 +707,7 @@ namespace DutilTests
707 Assert::Equal<BOOL>(FALSE, pVersion1->fInvalid);
708
709 NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion);
710 + Assert::Equal<WCHAR>(L'\0', pVersion2->chPrefix);
711 Assert::Equal<DWORD>(1, pVersion2->dwMajor);
712 Assert::Equal<DWORD>(2, pVersion2->dwMinor);
713 Assert::Equal<DWORD>(3, pVersion2->dwPatch);
@@ -674,6 +740,7 @@ namespace DutilTests
740 NativeAssert::Succeeded(hr, "VerParseVersion failed");
741
742 NativeAssert::StringEqual(wzVersion, pSource->sczVersion);
743 + Assert::Equal<WCHAR>(L'\0', pSource->chPrefix);
744 Assert::Equal<DWORD>(1, pSource->dwMajor);
745 Assert::Equal<DWORD>(2, pSource->dwMinor);
746 Assert::Equal<DWORD>(3, pSource->dwPatch);
@@ -688,6 +755,7 @@ namespace DutilTests
755
756 Assert::False(pSource == pCopy);
757 Assert::False(pSource->sczVersion == pCopy->sczVersion);
758 + Assert::Equal<WCHAR>(L'\0', pCopy->chPrefix);
759
760 hr = VerCompareParsedVersions(pSource, pCopy, &nResult);
761 NativeAssert::Succeeded(hr, "VerCompareParsedVersions failed");
@@ -705,7 +773,7 @@ namespace DutilTests
773 void VerCopyVersionCopiesPrereleaseVersion()
774 {
775 HRESULT hr = S_OK;
708 - LPCWSTR wzVersion = L"1.2.3.4-a.b.c.d.5.+abc123";
776 + LPCWSTR wzVersion = L"v1.2.3.4-a.b.c.d.5.+abc123";
777 VERUTIL_VERSION* pSource = NULL;
778 VERUTIL_VERSION* pCopy = NULL;
779 int nResult = 0;
@@ -715,7 +783,8 @@ namespace DutilTests
783 hr = VerParseVersion(wzVersion, 0, FALSE, &pSource);
784 NativeAssert::Succeeded(hr, "VerParseVersion failed");
785
718 - NativeAssert::StringEqual(wzVersion, pSource->sczVersion);
786 + NativeAssert::StringEqual(L"1.2.3.4-a.b.c.d.5.+abc123", pSource->sczVersion);
787 + Assert::Equal<WCHAR>(L'v', pSource->chPrefix);
788 Assert::Equal<DWORD>(1, pSource->dwMajor);
789 Assert::Equal<DWORD>(2, pSource->dwMinor);
790 Assert::Equal<DWORD>(3, pSource->dwPatch);
@@ -752,6 +821,7 @@ namespace DutilTests
821 Assert::False(pSource == pCopy);
822 Assert::False(pSource->sczVersion == pCopy->sczVersion);
823 Assert::False(pSource->rgReleaseLabels == pCopy->rgReleaseLabels);
824 + Assert::Equal<WCHAR>(L'v', pCopy->chPrefix);
825
826 hr = VerCompareParsedVersions(pSource, pCopy, &nResult);
827 NativeAssert::Succeeded(hr, "VerCompareParsedVersions failed");
@@ -808,6 +878,7 @@ namespace DutilTests
878 NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion7);
879
880 NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion);
881 + Assert::Equal<WCHAR>(L'\0', pVersion1->chPrefix);
882 Assert::Equal<DWORD>(0, pVersion1->dwMajor);
883 Assert::Equal<DWORD>(0, pVersion1->dwMinor);
884 Assert::Equal<DWORD>(0, pVersion1->dwPatch);
@@ -817,6 +888,7 @@ namespace DutilTests
888 Assert::Equal<BOOL>(TRUE, pVersion1->fInvalid);
889
890 NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion);
891 + Assert::Equal<WCHAR>(L'\0', pVersion2->chPrefix);
892 Assert::Equal<DWORD>(1, pVersion2->dwMajor);
893 Assert::Equal<DWORD>(0, pVersion2->dwMinor);
894 Assert::Equal<DWORD>(0, pVersion2->dwPatch);
@@ -826,6 +898,7 @@ namespace DutilTests
898 Assert::Equal<BOOL>(TRUE, pVersion2->fInvalid);
899
900 NativeAssert::StringEqual(wzVersion3, pVersion3->sczVersion);
901 + Assert::Equal<WCHAR>(L'\0', pVersion3->chPrefix);
902 Assert::Equal<DWORD>(2, pVersion3->dwMajor);
903 Assert::Equal<DWORD>(1, pVersion3->dwMinor);
904 Assert::Equal<DWORD>(0, pVersion3->dwPatch);
@@ -835,6 +908,7 @@ namespace DutilTests
908 Assert::Equal<BOOL>(TRUE, pVersion3->fInvalid);
909
910 NativeAssert::StringEqual(wzVersion4, pVersion4->sczVersion);
911 + Assert::Equal<WCHAR>(L'\0', pVersion4->chPrefix);
912 Assert::Equal<DWORD>(3, pVersion4->dwMajor);
913 Assert::Equal<DWORD>(2, pVersion4->dwMinor);
914 Assert::Equal<DWORD>(1, pVersion4->dwPatch);
@@ -844,6 +918,7 @@ namespace DutilTests
918 Assert::Equal<BOOL>(TRUE, pVersion4->fInvalid);
919
920 NativeAssert::StringEqual(wzVersion5, pVersion5->sczVersion);
921 + Assert::Equal<WCHAR>(L'\0', pVersion5->chPrefix);
922 Assert::Equal<DWORD>(4, pVersion5->dwMajor);
923 Assert::Equal<DWORD>(3, pVersion5->dwMinor);
924 Assert::Equal<DWORD>(2, pVersion5->dwPatch);
@@ -853,6 +928,7 @@ namespace DutilTests
928 Assert::Equal<BOOL>(TRUE, pVersion5->fInvalid);
929
930 NativeAssert::StringEqual(wzVersion6, pVersion6->sczVersion);
931 + Assert::Equal<WCHAR>(L'\0', pVersion6->chPrefix);
932 Assert::Equal<DWORD>(5, pVersion6->dwMajor);
933 Assert::Equal<DWORD>(0, pVersion6->dwMinor);
934 Assert::Equal<DWORD>(0, pVersion6->dwPatch);
@@ -862,6 +938,7 @@ namespace DutilTests
938 Assert::Equal<BOOL>(TRUE, pVersion6->fInvalid);
939
940 NativeAssert::StringEqual(wzVersion7, pVersion7->sczVersion);
941 + Assert::Equal<WCHAR>(L'\0', pVersion7->chPrefix);
942 Assert::Equal<DWORD>(6, pVersion7->dwMajor);
943 Assert::Equal<DWORD>(0, pVersion7->dwMinor);
944 Assert::Equal<DWORD>(0, pVersion7->dwPatch);
@@ -899,6 +976,7 @@ namespace DutilTests
976 NativeAssert::Succeeded(hr, "VerVersionFromQword failed");
977
978 NativeAssert::StringEqual(L"1.2.3.4", pVersion1->sczVersion);
979 + Assert::Equal<WCHAR>(L'\0', pVersion1->chPrefix);
980 Assert::Equal<DWORD>(1, pVersion1->dwMajor);
981 Assert::Equal<DWORD>(2, pVersion1->dwMinor);
982 Assert::Equal<DWORD>(3, pVersion1->dwPatch);