@joebigelow / wix / commits / bafc4f68

Update string versioning.

Update condition parsing to allow specific characters for versions. Log every time an invalid version is parsed.

Sean Hall committed Oct 18, 2020 at 14:05 UTC bafc4f682a798eb375d32c1f4777664aceb1e15f
9 files changed +225 -56
src/engine/condition.cpp
+73 -52
@@ -73,6 +73,12 @@ struct BURN_CONDITION_PARSE_CONTEXT
73 BOOL fError;
74 };
75
76 +struct BURN_CONDITION_OPERAND
77 +{
78 + BOOL fHidden;
79 + BURN_VARIANT Value;
80 +};
81 +
82
83 // internal function declarations
84
@@ -92,9 +98,9 @@ static HRESULT ParseTerm(
98 __in BURN_CONDITION_PARSE_CONTEXT* pContext,
99 __out BOOL* pf
100 );
95 -static HRESULT ParseValue(
101 +static HRESULT ParseOperand(
102 __in BURN_CONDITION_PARSE_CONTEXT* pContext,
97 - __out BURN_VARIANT* pValue
103 + __out BURN_CONDITION_OPERAND* pOperand
104 );
105 static HRESULT Expect(
106 __in BURN_CONDITION_PARSE_CONTEXT* pContext,
@@ -103,10 +109,10 @@ static HRESULT Expect(
109 static HRESULT NextSymbol(
110 __in BURN_CONDITION_PARSE_CONTEXT* pContext
111 );
106 -static HRESULT CompareValues(
112 +static HRESULT CompareOperands(
113 __in BURN_SYMBOL_TYPE comparison,
108 - __in BURN_VARIANT leftOperand,
109 - __in BURN_VARIANT rightOperand,
114 + __in BURN_CONDITION_OPERAND* pLeftOperand,
115 + __in BURN_CONDITION_OPERAND* pRightOperand,
116 __out BOOL* pfResult
117 );
118 static HRESULT CompareStringValues(
@@ -342,8 +348,8 @@ static HRESULT ParseTerm(
348 )
349 {
350 HRESULT hr = S_OK;
345 - BURN_VARIANT firstValue = { };
346 - BURN_VARIANT secondValue = { };
351 + BURN_CONDITION_OPERAND firstOperand = { };
352 + BURN_CONDITION_OPERAND secondOperand = { };
353
354 if (BURN_SYMBOL_TYPE_LPAREN == pContext->NextSymbol.Type)
355 {
@@ -359,8 +365,8 @@ static HRESULT ParseTerm(
365 ExitFunction1(hr = S_OK);
366 }
367
362 - hr = ParseValue(pContext, &firstValue);
363 - ExitOnFailure(hr, "Failed to parse value.");
368 + hr = ParseOperand(pContext, &firstOperand);
369 + ExitOnFailure(hr, "Failed to parse operand.");
370
371 if (COMPARISON & pContext->NextSymbol.Type)
372 {
@@ -369,24 +375,24 @@ static HRESULT ParseTerm(
375 hr = NextSymbol(pContext);
376 ExitOnFailure(hr, "Failed to read next symbol.");
377
372 - hr = ParseValue(pContext, &secondValue);
373 - ExitOnFailure(hr, "Failed to parse value.");
378 + hr = ParseOperand(pContext, &secondOperand);
379 + ExitOnFailure(hr, "Failed to parse operand.");
380
375 - hr = CompareValues(comparison, firstValue, secondValue, pf);
376 - ExitOnFailure(hr, "Failed to compare value.");
381 + hr = CompareOperands(comparison, &firstOperand, &secondOperand, pf);
382 + ExitOnFailure(hr, "Failed to compare operands.");
383 }
384 else
385 {
386 LONGLONG llValue = 0;
387 LPWSTR sczValue = NULL;
388 VERUTIL_VERSION* pVersion = NULL;
383 - switch (firstValue.Type)
389 + switch (firstOperand.Value.Type)
390 {
391 case BURN_VARIANT_TYPE_NONE:
392 *pf = FALSE;
393 break;
394 case BURN_VARIANT_TYPE_STRING:
389 - hr = BVariantGetString(&firstValue, &sczValue);
395 + hr = BVariantGetString(&firstOperand.Value, &sczValue);
396 if (SUCCEEDED(hr))
397 {
398 *pf = sczValue && *sczValue;
@@ -394,7 +400,7 @@ static HRESULT ParseTerm(
400 StrSecureZeroFreeString(sczValue);
401 break;
402 case BURN_VARIANT_TYPE_NUMERIC:
397 - hr = BVariantGetNumeric(&firstValue, &llValue);
403 + hr = BVariantGetNumeric(&firstOperand.Value, &llValue);
404 if (SUCCEEDED(hr))
405 {
406 *pf = 0 != llValue;
@@ -402,7 +408,7 @@ static HRESULT ParseTerm(
408 SecureZeroMemory(&llValue, sizeof(llValue));
409 break;
410 case BURN_VARIANT_TYPE_VERSION:
405 - hr = BVariantGetVersion(&firstValue, &pVersion);
411 + hr = BVariantGetVersionHidden(&firstOperand.Value, firstOperand.fHidden, &pVersion);
412 if (SUCCEEDED(hr))
413 {
414 *pf = 0 != *pVersion->sczVersion;
@@ -415,14 +421,14 @@ static HRESULT ParseTerm(
421 }
422
423 LExit:
418 - BVariantUninitialize(&firstValue);
419 - BVariantUninitialize(&secondValue);
424 + BVariantUninitialize(&firstOperand.Value);
425 + BVariantUninitialize(&secondOperand.Value);
426 return hr;
427 }
428
423 -static HRESULT ParseValue(
429 +static HRESULT ParseOperand(
430 __in BURN_CONDITION_PARSE_CONTEXT* pContext,
425 - __out BURN_VARIANT* pValue
431 + __out BURN_CONDITION_OPERAND* pOperand
432 )
433 {
434 HRESULT hr = S_OK;
@@ -434,16 +440,19 @@ static HRESULT ParseValue(
440 Assert(BURN_VARIANT_TYPE_STRING == pContext->NextSymbol.Value.Type);
441
442 // find variable
437 - hr = VariableGetVariant(pContext->pVariables, pContext->NextSymbol.Value.sczValue, pValue);
443 + hr = VariableGetVariant(pContext->pVariables, pContext->NextSymbol.Value.sczValue, &pOperand->Value);
444 if (E_NOTFOUND != hr)
445 {
446 ExitOnRootFailure(hr, "Failed to find variable.");
447 +
448 + hr = VariableIsHidden(pContext->pVariables, pContext->NextSymbol.Value.sczValue, &pOperand->fHidden);
449 + ExitOnRootFailure(hr, "Failed to get if variable is hidden.");
450 }
451
443 - if (BURN_VARIANT_TYPE_FORMATTED == pValue->Type)
452 + if (BURN_VARIANT_TYPE_FORMATTED == pOperand->Value.Type)
453 {
454 // TODO: actually format the value?
446 - hr = BVariantChangeType(pValue, BURN_VARIANT_TYPE_STRING);
455 + hr = BVariantChangeType(&pOperand->Value, BURN_VARIANT_TYPE_STRING);
456 ExitOnRootFailure(hr, "Failed to change variable '%ls' type for condition '%ls'", pContext->NextSymbol.Value.sczValue, pContext->wzCondition);
457 }
458 break;
@@ -451,8 +460,9 @@ static HRESULT ParseValue(
460 case BURN_SYMBOL_TYPE_NUMBER: __fallthrough;
461 case BURN_SYMBOL_TYPE_LITERAL: __fallthrough;
462 case BURN_SYMBOL_TYPE_VERSION:
463 + pOperand->fHidden = FALSE;
464 // steal value of symbol
455 - memcpy_s(pValue, sizeof(BURN_VARIANT), &pContext->NextSymbol.Value, sizeof(BURN_VARIANT));
465 + memcpy_s(&pOperand->Value, sizeof(BURN_VARIANT), &pContext->NextSymbol.Value, sizeof(BURN_VARIANT));
466 memset(&pContext->NextSymbol.Value, 0, sizeof(BURN_VARIANT));
467 break;
468
@@ -692,8 +702,13 @@ static HRESULT NextSymbol(
702 do
703 {
704 ++n;
695 - ::GetStringTypeW(CT_CTYPE1, &pContext->wzRead[n], 1, &charType);
696 - } while (L'\0' != pContext->wzRead[n] && C1_BLANK != (C1_BLANK & charType));
705 + } while (pContext->wzRead[n] >= L'0' && pContext->wzRead[n] <= L'9' ||
706 + pContext->wzRead[n] >= L'A' && pContext->wzRead[n] <= L'Z' ||
707 + pContext->wzRead[n] >= L'a' && pContext->wzRead[n] <= L'z' ||
708 + pContext->wzRead[n] == L'_' ||
709 + pContext->wzRead[n] == L'+' ||
710 + pContext->wzRead[n] == L'-' ||
711 + pContext->wzRead[n] == L'.');
712
713 // Symbols don't encrypt their value, so can access the value directly.
714 hr = VerParseVersion(&pContext->wzRead[1], n - 1, FALSE, &pContext->NextSymbol.Value.pValue);
@@ -703,6 +718,10 @@ static HRESULT NextSymbol(
718 hr = E_INVALIDDATA;
719 ExitOnRootFailure(hr, "Failed to parse condition \"%ls\". Invalid version format, at position %d.", pContext->wzCondition, iPosition);
720 }
721 + else if (pContext->NextSymbol.Value.pValue->fInvalid)
722 + {
723 + LogId(REPORT_WARNING, MSG_CONDITION_INVALID_VERSION, pContext->wzCondition, pContext->NextSymbol.Value.pValue->sczVersion);
724 + }
725
726 pContext->NextSymbol.Value.Type = BURN_VARIANT_TYPE_VERSION;
727 pContext->NextSymbol.Type = BURN_SYMBOL_TYPE_VERSION;
@@ -755,12 +774,12 @@ LExit:
774 }
775
776 //
758 -// CompareValues - compares two variant values using a given comparison.
777 +// CompareOperands - compares two variant values using a given comparison.
778 //
760 -static HRESULT CompareValues(
779 +static HRESULT CompareOperands(
780 __in BURN_SYMBOL_TYPE comparison,
762 - __in BURN_VARIANT leftOperand,
763 - __in BURN_VARIANT rightOperand,
781 + __in BURN_CONDITION_OPERAND* pLeftOperand,
782 + __in BURN_CONDITION_OPERAND* pRightOperand,
783 __out BOOL* pfResult
784 )
785 {
@@ -771,37 +790,39 @@ static HRESULT CompareValues(
790 LONGLONG llRight = 0;
791 VERUTIL_VERSION* pVersionRight = 0;
792 LPWSTR sczRight = NULL;
793 + BURN_VARIANT* pLeftValue = &pLeftOperand->Value;
794 + BURN_VARIANT* pRightValue = &pRightOperand->Value;
795
796 // get values to compare based on type
776 - if (BURN_VARIANT_TYPE_STRING == leftOperand.Type && BURN_VARIANT_TYPE_STRING == rightOperand.Type)
797 + if (BURN_VARIANT_TYPE_STRING == pLeftValue->Type && BURN_VARIANT_TYPE_STRING == pRightValue->Type)
798 {
778 - hr = BVariantGetString(&leftOperand, &sczLeft);
799 + hr = BVariantGetString(pLeftValue, &sczLeft);
800 ExitOnFailure(hr, "Failed to get the left string");
780 - hr = BVariantGetString(&rightOperand, &sczRight);
801 + hr = BVariantGetString(pRightValue, &sczRight);
802 ExitOnFailure(hr, "Failed to get the right string");
803 hr = CompareStringValues(comparison, sczLeft, sczRight, pfResult);
804 }
784 - else if (BURN_VARIANT_TYPE_NUMERIC == leftOperand.Type && BURN_VARIANT_TYPE_NUMERIC == rightOperand.Type)
805 + else if (BURN_VARIANT_TYPE_NUMERIC == pLeftValue->Type && BURN_VARIANT_TYPE_NUMERIC == pRightValue->Type)
806 {
786 - hr = BVariantGetNumeric(&leftOperand, &llLeft);
807 + hr = BVariantGetNumeric(pLeftValue, &llLeft);
808 ExitOnFailure(hr, "Failed to get the left numeric");
788 - hr = BVariantGetNumeric(&rightOperand, &llRight);
809 + hr = BVariantGetNumeric(pRightValue, &llRight);
810 ExitOnFailure(hr, "Failed to get the right numeric");
811 hr = CompareIntegerValues(comparison, llLeft, llRight, pfResult);
812 }
792 - else if (BURN_VARIANT_TYPE_VERSION == leftOperand.Type && BURN_VARIANT_TYPE_VERSION == rightOperand.Type)
813 + else if (BURN_VARIANT_TYPE_VERSION == pLeftValue->Type && BURN_VARIANT_TYPE_VERSION == pRightValue->Type)
814 {
794 - hr = BVariantGetVersion(&leftOperand, &pVersionLeft);
815 + hr = BVariantGetVersionHidden(pLeftValue, pLeftOperand->fHidden, &pVersionLeft);
816 ExitOnFailure(hr, "Failed to get the left version");
796 - hr = BVariantGetVersion(&rightOperand, &pVersionRight);
817 + hr = BVariantGetVersionHidden(pRightValue, pRightOperand->fHidden, &pVersionRight);
818 ExitOnFailure(hr, "Failed to get the right version");
819 hr = CompareVersionValues(comparison, pVersionLeft, pVersionRight, pfResult);
820 }
800 - else if (BURN_VARIANT_TYPE_VERSION == leftOperand.Type && BURN_VARIANT_TYPE_STRING == rightOperand.Type)
821 + else if (BURN_VARIANT_TYPE_VERSION == pLeftValue->Type && BURN_VARIANT_TYPE_STRING == pRightValue->Type)
822 {
802 - hr = BVariantGetVersion(&leftOperand, &pVersionLeft);
823 + hr = BVariantGetVersionHidden(pLeftValue, pLeftOperand->fHidden, &pVersionLeft);
824 ExitOnFailure(hr, "Failed to get the left version");
804 - hr = BVariantGetVersion(&rightOperand, &pVersionRight);
825 + hr = BVariantGetVersionHidden(pRightValue, pRightOperand->fHidden, &pVersionRight);
826 if (FAILED(hr))
827 {
828 if (DISP_E_TYPEMISMATCH != hr)
@@ -816,11 +837,11 @@ static HRESULT CompareValues(
837 hr = CompareVersionValues(comparison, pVersionLeft, pVersionRight, pfResult);
838 }
839 }
819 - else if (BURN_VARIANT_TYPE_STRING == leftOperand.Type && BURN_VARIANT_TYPE_VERSION == rightOperand.Type)
840 + else if (BURN_VARIANT_TYPE_STRING == pLeftValue->Type && BURN_VARIANT_TYPE_VERSION == pRightValue->Type)
841 {
821 - hr = BVariantGetVersion(&rightOperand, &pVersionRight);
842 + hr = BVariantGetVersionHidden(pRightValue, pRightOperand->fHidden, &pVersionRight);
843 ExitOnFailure(hr, "Failed to get the right version");
823 - hr = BVariantGetVersion(&leftOperand, &pVersionLeft);
844 + hr = BVariantGetVersionHidden(pLeftValue, pLeftOperand->fHidden, &pVersionLeft);
845 if (FAILED(hr))
846 {
847 if (DISP_E_TYPEMISMATCH != hr)
@@ -835,11 +856,11 @@ static HRESULT CompareValues(
856 hr = CompareVersionValues(comparison, pVersionLeft, pVersionRight, pfResult);
857 }
858 }
838 - else if (BURN_VARIANT_TYPE_NUMERIC == leftOperand.Type && BURN_VARIANT_TYPE_STRING == rightOperand.Type)
859 + else if (BURN_VARIANT_TYPE_NUMERIC == pLeftValue->Type && BURN_VARIANT_TYPE_STRING == pRightValue->Type)
860 {
840 - hr = BVariantGetNumeric(&leftOperand, &llLeft);
861 + hr = BVariantGetNumeric(pLeftValue, &llLeft);
862 ExitOnFailure(hr, "Failed to get the left numeric");
842 - hr = BVariantGetNumeric(&rightOperand, &llRight);
863 + hr = BVariantGetNumeric(pRightValue, &llRight);
864 if (FAILED(hr))
865 {
866 if (DISP_E_TYPEMISMATCH != hr)
@@ -854,11 +875,11 @@ static HRESULT CompareValues(
875 hr = CompareIntegerValues(comparison, llLeft, llRight, pfResult);
876 }
877 }
857 - else if (BURN_VARIANT_TYPE_STRING == leftOperand.Type && BURN_VARIANT_TYPE_NUMERIC == rightOperand.Type)
878 + else if (BURN_VARIANT_TYPE_STRING == pLeftValue->Type && BURN_VARIANT_TYPE_NUMERIC == pRightValue->Type)
879 {
859 - hr = BVariantGetNumeric(&rightOperand, &llRight);
880 + hr = BVariantGetNumeric(pRightValue, &llRight);
881 ExitOnFailure(hr, "Failed to get the right numeric");
861 - hr = BVariantGetNumeric(&leftOperand, &llLeft);
882 + hr = BVariantGetNumeric(pLeftValue, &llLeft);
883 if (FAILED(hr))
884 {
885 if (DISP_E_TYPEMISMATCH != hr)
src/engine/engine.mc
+42
@@ -114,6 +114,13 @@ Language=English
114 Connected to elevated engine.
115 .
116
117 +MessageId=13
118 +Severity=Warning
119 +SymbolicName=MSG_MANIFEST_INVALID_VERSION
120 +Language=English
121 +The manifest contains an invalid version string: '%1!ls!'
122 +.
123 +
124 MessageId=51
125 Severity=Error
126 SymbolicName=MSG_FAILED_PARSE_CONDITION
@@ -156,6 +163,13 @@ Language=English
163 Application canceled operation: %2!ls!, error: %1!ls!
164 .
165
166 +MessageId=57
167 +Severity=Warning
168 +SymbolicName=MSG_CONDITION_INVALID_VERSION
169 +Language=English
170 +Condition '%1!ls!' contains invalid version string '%2!ls!'.
171 +.
172 +
173 MessageId=100
174 Severity=Success
175 SymbolicName=MSG_DETECT_BEGIN
@@ -233,6 +247,20 @@ Language=English
247 Could not calculate patch applicability for target product code: %1!ls!, context: %2!hs!, reason: 0x%3!x!
248 .
249
250 +MessageId=122
251 +Severity=Warning
252 +SymbolicName=MSG_RELATED_PACKAGE_INVALID_VERSION
253 +Language=English
254 +Related package: '%1!ls!' has invalid version: %2!ls!
255 +.
256 +
257 +MessageId=123
258 +Severity=Warning
259 +SymbolicName=MSG_DETECTED_MSI_PACKAGE_INVALID_VERSION
260 +Language=English
261 +Detected msi package with invalid version, product code: '%1!ls!', version: '%2!ls!'
262 +.
263 +
264 MessageId=151
265 Severity=Error
266 SymbolicName=MSG_FAILED_DETECT_PACKAGE
@@ -836,6 +864,20 @@ Language=English
864 Variable: %1!ls!
865 .
866
867 +MessageId=411
868 +Severity=Warning
869 +SymbolicName=MSG_VARIABLE_INVALID_VERSION
870 +Language=English
871 +The variable '%1!ls!' is being set with an invalid version string.
872 +.
873 +
874 +MessageId=412
875 +Severity=Warning
876 +SymbolicName=MSG_INVALID_VERSION_COERSION
877 +Language=English
878 +The string '%1!ls!' could not be coerced to a valid version.
879 +.
880 +
881 MessageId=420
882 Severity=Success
883 SymbolicName=MSG_RESUME_AU_STARTING
src/engine/msiengine.cpp
+35
@@ -82,6 +82,11 @@ extern "C" HRESULT MsiEngineParsePackageFromXml(
82 hr = VerParseVersion(scz, 0, FALSE, &pPackage->Msi.pVersion);
83 ExitOnFailure(hr, "Failed to parse @Version: %ls", scz);
84
85 + if (pPackage->Msi.pVersion->fInvalid)
86 + {
87 + LogId(REPORT_WARNING, MSG_MANIFEST_INVALID_VERSION, scz);
88 + }
89 +
90 // @UpgradeCode
91 hr = XmlGetAttributeEx(pixnMsiPackage, L"UpgradeCode", &pPackage->Msi.sczUpgradeCode);
92 if (E_NOTFOUND != hr)
@@ -420,6 +425,11 @@ extern "C" HRESULT MsiEngineDetectPackage(
425 hr = VerParseVersion(sczInstalledVersion, 0, FALSE, &pPackage->Msi.pInstalledVersion);
426 ExitOnFailure(hr, "Failed to parse installed version: '%ls' for ProductCode: %ls", sczInstalledVersion, pPackage->Msi.sczProductCode);
427
428 + if (pPackage->Msi.pInstalledVersion->fInvalid)
429 + {
430 + LogId(REPORT_WARNING, MSG_DETECTED_MSI_PACKAGE_INVALID_VERSION, pPackage->Msi.sczProductCode, sczInstalledVersion);
431 + }
432 +
433 // compare versions
434 hr = VerCompareParsedVersions(pPackage->Msi.pVersion, pPackage->Msi.pInstalledVersion, &nCompareResult);
435 ExitOnFailure(hr, "Failed to compare version '%ls' to installed version: '%ls'", pPackage->Msi.pVersion->sczVersion, pPackage->Msi.pInstalledVersion->sczVersion);
@@ -460,6 +470,11 @@ extern "C" HRESULT MsiEngineDetectPackage(
470 hr = VerParseVersion(sczInstalledVersion, 0, FALSE, &pVersion);
471 ExitOnFailure(hr, "Failed to parse dependency version: '%ls' for ProductCode: %ls", sczInstalledVersion, sczInstalledProductCode);
472
473 + if (pVersion->fInvalid)
474 + {
475 + LogId(REPORT_WARNING, MSG_DETECTED_MSI_PACKAGE_INVALID_VERSION, sczInstalledProductCode, sczInstalledVersion);
476 + }
477 +
478 // compare versions
479 hr = VerCompareParsedVersions(pPackage->Msi.pVersion, pVersion, &nCompareResult);
480 ExitOnFailure(hr, "Failed to compare version '%ls' to dependency version: '%ls'", pPackage->Msi.pVersion->sczVersion, pVersion->sczVersion);
@@ -536,6 +551,11 @@ extern "C" HRESULT MsiEngineDetectPackage(
551 hr = VerParseVersion(sczInstalledVersion, 0, FALSE, &pVersion);
552 ExitOnFailure(hr, "Failed to parse related installed version: '%ls' for ProductCode: %ls", sczInstalledVersion, wzProductCode);
553
554 + if (pVersion->fInvalid)
555 + {
556 + LogId(REPORT_WARNING, MSG_DETECTED_MSI_PACKAGE_INVALID_VERSION, wzProductCode, sczInstalledVersion);
557 + }
558 +
559 // compare versions
560 if (pRelatedMsi->fMinProvided)
561 {
@@ -1052,6 +1072,11 @@ extern "C" HRESULT MsiEngineAddCompatiblePackage(
1072
1073 hr = VerParseVersion(sczInstalledVersion, 0, FALSE, &pCompatiblePackage->Msi.pVersion);
1074 ExitOnFailure(hr, "Failed to parse version: '%ls' for ProductCode: %ls", sczInstalledVersion, pCompatiblePackage->Msi.sczProductCode);
1075 +
1076 + if (pCompatiblePackage->Msi.pVersion->fInvalid)
1077 + {
1078 + LogId(REPORT_WARNING, MSG_DETECTED_MSI_PACKAGE_INVALID_VERSION, pCompatiblePackage->Msi.sczProductCode, sczInstalledVersion);
1079 + }
1080 }
1081
1082 // For now, copy enough information to support uninstalling the newer, compatible package.
@@ -1506,6 +1531,11 @@ static HRESULT ParseRelatedMsiFromXml(
1531 hr = VerParseVersion(scz, 0, FALSE, &pRelatedMsi->pMinVersion);
1532 ExitOnFailure(hr, "Failed to parse @MinVersion: %ls", scz);
1533
1534 + if (pRelatedMsi->pMinVersion->fInvalid)
1535 + {
1536 + LogId(REPORT_WARNING, MSG_MANIFEST_INVALID_VERSION, scz);
1537 + }
1538 +
1539 // flag that we have a min version
1540 pRelatedMsi->fMinProvided = TRUE;
1541
@@ -1523,6 +1553,11 @@ static HRESULT ParseRelatedMsiFromXml(
1553 hr = VerParseVersion(scz, 0, FALSE, &pRelatedMsi->pMaxVersion);
1554 ExitOnFailure(hr, "Failed to parse @MaxVersion: %ls", scz);
1555
1556 + if (pRelatedMsi->pMaxVersion->fInvalid)
1557 + {
1558 + LogId(REPORT_WARNING, MSG_MANIFEST_INVALID_VERSION, scz);
1559 + }
1560 +
1561 // flag that we have a max version
1562 pRelatedMsi->fMaxProvided = TRUE;
1563
src/engine/registration.cpp
+5
@@ -136,6 +136,11 @@ extern "C" HRESULT RegistrationParseFromXml(
136 hr = VerParseVersion(scz, 0, FALSE, &pRegistration->pVersion);
137 ExitOnFailure(hr, "Failed to parse @Version: %ls", scz);
138
139 + if (pRegistration->pVersion->fInvalid)
140 + {
141 + LogId(REPORT_WARNING, MSG_MANIFEST_INVALID_VERSION, scz);
142 + }
143 +
144 // @ProviderKey
145 hr = XmlGetAttributeEx(pixnRegistrationNode, L"ProviderKey", &pRegistration->sczProviderKey);
146 ExitOnFailure(hr, "Failed to get @ProviderKey.");
src/engine/relatedbundle.cpp
+5
@@ -414,6 +414,11 @@ static HRESULT LoadRelatedBundleFromKey(
414 hr = VerParseVersion(sczBundleVersion, 0, FALSE, &pRelatedBundle->pVersion);
415 ExitOnFailure(hr, "Failed to parse pseudo bundle version: %ls", sczBundleVersion);
416
417 + if (pRelatedBundle->pVersion->fInvalid)
418 + {
419 + LogId(REPORT_WARNING, MSG_RELATED_PACKAGE_INVALID_VERSION, wzRelatedBundleId, sczBundleVersion);
420 + }
421 +
422 hr = RegReadString(hkBundleId, BURN_REGISTRATION_REGISTRY_BUNDLE_CACHE_PATH, &sczCachePath);
423 ExitOnFailure(hr, "Failed to read cache path from registry for bundle: %ls", wzRelatedBundleId);
424
src/engine/variable.cpp
+11 -1
@@ -393,6 +393,11 @@ extern "C" HRESULT VariablesParseFromXml(
393 hr = BVariantChangeType(&value, valueType);
394 ExitOnFailure(hr, "Failed to change variant type.");
395
396 + if (BURN_VARIANT_TYPE_VERSION == valueType && value.pValue->fInvalid)
397 + {
398 + LogId(REPORT_WARNING, MSG_VARIABLE_INVALID_VERSION, sczId);
399 + }
400 +
401 // find existing variable
402 hr = FindVariableIndexByName(pVariables, sczId, &iVariable);
403 ExitOnFailure(hr, "Failed to find variable value '%ls'.", sczId);
@@ -584,7 +589,7 @@ extern "C" HRESULT VariableGetVersion(
589 }
590 ExitOnFailure(hr, "Failed to get value of variable: %ls", wzVariable);
591
587 - hr = BVariantGetVersion(&pVariable->Value, ppValue);
592 + hr = BVariantGetVersionHidden(&pVariable->Value, pVariable->fHidden, ppValue);
593 ExitOnFailure(hr, "Failed to get value as version for variable: %ls", wzVariable);
594
595 LExit:
@@ -1575,6 +1580,11 @@ static HRESULT SetVariableValue(
1580 break;
1581 }
1582 }
1583 +
1584 + if (BURN_VARIANT_TYPE_VERSION == pVariant->Type && pVariant->pValue->fInvalid)
1585 + {
1586 + LogId(REPORT_WARNING, MSG_VARIABLE_INVALID_VERSION, wzVariable);
1587 + }
1588 }
1589
1590 // Update variable value.
src/engine/variant.cpp
+43 -3
@@ -6,6 +6,12 @@
6
7 // internal function declarations
8
9 +static HRESULT GetVersionInternal(
10 + __in BURN_VARIANT* pVariant,
11 + __in BOOL fHidden,
12 + __in BOOL fSilent,
13 + __out VERUTIL_VERSION** ppValue
14 + );
15 static HRESULT BVariantEncryptString(
16 __in BURN_VARIANT* pVariant,
17 __in BOOL fEncrypt
@@ -129,6 +135,36 @@ extern "C" HRESULT BVariantGetVersion(
135 __in BURN_VARIANT* pVariant,
136 __out VERUTIL_VERSION** ppValue
137 )
138 +{
139 + return GetVersionInternal(pVariant, FALSE, FALSE, ppValue);
140 +}
141 +
142 +// The contents of ppValue may be sensitive, should keep encrypted and SecureZeroMemory.
143 +extern "C" HRESULT BVariantGetVersionHidden(
144 + __in BURN_VARIANT* pVariant,
145 + __in BOOL fHidden,
146 + __out VERUTIL_VERSION** ppValue
147 + )
148 +{
149 + return GetVersionInternal(pVariant, fHidden, FALSE, ppValue);
150 +}
151 +
152 +// The contents of ppValue may be sensitive, should keep encrypted and SecureZeroMemory.
153 +extern "C" HRESULT BVariantGetVersionSilent(
154 + __in BURN_VARIANT* pVariant,
155 + __in BOOL fSilent,
156 + __out VERUTIL_VERSION** ppValue
157 + )
158 +{
159 + return GetVersionInternal(pVariant, FALSE, fSilent, ppValue);
160 +}
161 +
162 +static HRESULT GetVersionInternal(
163 + __in BURN_VARIANT* pVariant,
164 + __in BOOL fHidden,
165 + __in BOOL fSilent,
166 + __out VERUTIL_VERSION** ppValue
167 + )
168 {
169 HRESULT hr = S_OK;
170 LONGLONG llValue = 0;
@@ -152,6 +188,10 @@ extern "C" HRESULT BVariantGetVersion(
188 {
189 hr = DISP_E_TYPEMISMATCH;
190 }
191 + else if (!fSilent && (*ppValue)->fInvalid)
192 + {
193 + LogId(REPORT_WARNING, MSG_INVALID_VERSION_COERSION, fHidden ? L"*****" : sczValue);
194 + }
195 }
196 StrSecureZeroFreeString(sczValue);
197 break;
@@ -282,7 +322,7 @@ extern "C" HRESULT BVariantSetValue(
322 StrSecureZeroFreeString(sczValue);
323 break;
324 case BURN_VARIANT_TYPE_VERSION:
285 - hr = BVariantGetVersion(pValue, &pVersionValue);
325 + hr = BVariantGetVersionSilent(pValue, TRUE, &pVersionValue);
326 if (SUCCEEDED(hr))
327 {
328 hr = BVariantSetVersion(pVariant, pVersionValue);
@@ -333,7 +373,7 @@ extern "C" HRESULT BVariantCopy(
373 StrSecureZeroFreeString(sczValue);
374 break;
375 case BURN_VARIANT_TYPE_VERSION:
336 - hr = BVariantGetVersion(pSource, &pVersionValue);
376 + hr = BVariantGetVersionSilent(pSource, TRUE, &pVersionValue);
377 if (SUCCEEDED(hr))
378 {
379 hr = BVariantSetVersion(pTarget, pVersionValue);
@@ -383,7 +423,7 @@ extern "C" HRESULT BVariantChangeType(
423 hr = BVariantGetString(pVariant, &variant.sczValue);
424 break;
425 case BURN_VARIANT_TYPE_VERSION:
386 - hr = BVariantGetVersion(pVariant, &variant.pValue);
426 + hr = BVariantGetVersionSilent(pVariant, TRUE, &variant.pValue);
427 break;
428 default:
429 ExitFunction1(hr = E_INVALIDARG);
src/engine/variant.h
+10
@@ -51,6 +51,16 @@ HRESULT BVariantGetVersion(
51 __in BURN_VARIANT* pVariant,
52 __out VERUTIL_VERSION** ppValue
53 );
54 +HRESULT BVariantGetVersionHidden(
55 + __in BURN_VARIANT* pVariant,
56 + __in BOOL fHidden,
57 + __out VERUTIL_VERSION** ppValue
58 + );
59 +HRESULT BVariantGetVersionSilent(
60 + __in BURN_VARIANT* pVariant,
61 + __in BOOL fSilent,
62 + __out VERUTIL_VERSION** ppValue
63 + );
64 HRESULT BVariantSetNumeric(
65 __in BURN_VARIANT* pVariant,
66 __in LONGLONG llValue
src/test/BurnUnitTest/VariableTest.cpp
+1
@@ -273,6 +273,7 @@ namespace Bootstrapper
273 Assert::True(EvaluateConditionHelper(&variables, L"vPROP21 = 1"));
274 Assert::True(EvaluateConditionHelper(&variables, L"PROP23 = v1.1.1"));
275 Assert::True(EvaluateConditionHelper(&variables, L"v1.1.1 = PROP23"));
276 + Assert::False(EvaluateConditionHelper(&variables, L"v1.1.1<>PROP23"));
277 Assert::True(EvaluateConditionHelper(&variables, L"PROP1 <> v1.1.1"));
278 Assert::True(EvaluateConditionHelper(&variables, L"v1.1.1 <> PROP1"));
279