From 28c8abfda013d6aa568fde8b26da65522748d376 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Mon, 1 Aug 2022 17:07:49 -0500 Subject: Downgrade error to warning when search refs a reserved prefix variable. The engine doesn't actually prevent external callers from setting variables that start with 'Wix'. --- .../Data/BundleVariableNameRule.cs | 33 ++++++ .../Services/IBundleValidator.cs | 26 ++++- .../Services/IParseHelper.cs | 3 +- src/burn/test/BurnUnitTest/VariableTest.cpp | 33 ++++++ .../BundleUsingDiscouragedVariableNames.wxs | 19 ++++ .../WixToolsetTest.Util/UtilExtensionFixture.cs | 63 +++++++++-- .../PerformBundleBackendValidationCommand.cs | 4 +- .../ExtensibilityServices/BurnBackendHelper.cs | 14 ++- src/wix/WixToolset.Core/CompilerWarnings.cs | 12 +++ .../ExtensibilityServices/BundleValidator.cs | 120 ++++++++++++++++++++- .../ExtensibilityServices/ParseHelper.cs | 12 +-- .../BadInputFixture.cs | 24 +++-- .../BundleWithInvalidLocValues.wxl | 2 + .../BundleWithInvalidLocValues.wxs | 2 + .../BundleWithReservedVariableNames.wxs | 1 - 15 files changed, 333 insertions(+), 35 deletions(-) create mode 100644 src/api/wix/WixToolset.Extensibility/Data/BundleVariableNameRule.cs create mode 100644 src/ext/Util/test/WixToolsetTest.Util/TestData/BundleWithSearches/BundleUsingDiscouragedVariableNames.wxs (limited to 'src') diff --git a/src/api/wix/WixToolset.Extensibility/Data/BundleVariableNameRule.cs b/src/api/wix/WixToolset.Extensibility/Data/BundleVariableNameRule.cs new file mode 100644 index 00000000..eb6f7543 --- /dev/null +++ b/src/api/wix/WixToolset.Extensibility/Data/BundleVariableNameRule.cs @@ -0,0 +1,33 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Extensibility.Data +{ + using System; + + /// + /// When validating a bundle variable name, which special restrictions to ignore. + /// + [Flags] + public enum BundleVariableNameRule + { + /// + /// Enforce all special restrictions. + /// + EnforceAllRestrictions = 0x0, + + /// + /// Allow names of built-in variables. + /// + CanBeBuiltIn = 0x1, + + /// + /// Allow names of well-known variables. + /// + CanBeWellKnown = 0x2, + + /// + /// Allow names that are not built-in and are not well-known and start with 'Wix'. + /// + CanHaveReservedPrefix = 0x4, + } +} diff --git a/src/api/wix/WixToolset.Extensibility/Services/IBundleValidator.cs b/src/api/wix/WixToolset.Extensibility/Services/IBundleValidator.cs index 43f65fc8..3753d16d 100644 --- a/src/api/wix/WixToolset.Extensibility/Services/IBundleValidator.cs +++ b/src/api/wix/WixToolset.Extensibility/Services/IBundleValidator.cs @@ -33,15 +33,35 @@ namespace WixToolset.Extensibility.Services bool ValidateBundleMsiPropertyName(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string propertyName); /// - /// Validates a Bundle variable name and displays an error for an illegal value. + /// Validates a Bundle variable name that is being used to declare a Variable in the bundle manifest and displays an error for an illegal value. /// /// /// /// /// - /// Whether to bypass checks for reserved values. /// Whether the name is valid. - bool ValidateBundleVariableName(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName, bool allowBuiltIn); + bool ValidateBundleVariableNameDeclaration(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName); + + /// + /// Validates a Bundle variable name that is being used to reference a Variable and displays an error for an illegal value. + /// + /// + /// + /// + /// + /// + /// Whether the name is valid. + bool ValidateBundleVariableNameValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName, BundleVariableNameRule nameRule); + + /// + /// Validates a Bundle variable name that is being used to set its value and displays an error for an illegal value. + /// + /// + /// + /// + /// + /// Whether the name is valid. + bool ValidateBundleVariableNameTarget(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName); /// /// Validates a bundle condition and displays an error for an illegal value. diff --git a/src/api/wix/WixToolset.Extensibility/Services/IParseHelper.cs b/src/api/wix/WixToolset.Extensibility/Services/IParseHelper.cs index a8246b9b..3a3c2ceb 100644 --- a/src/api/wix/WixToolset.Extensibility/Services/IParseHelper.cs +++ b/src/api/wix/WixToolset.Extensibility/Services/IParseHelper.cs @@ -246,8 +246,9 @@ namespace WixToolset.Extensibility.Services /// /// Source line information about the owner element. /// The attribute containing the value to get. + /// A rule for the contents of the value. If the contents do not follow the rule, an error is thrown. /// The attribute's value. - string GetAttributeBundleVariableNameValue(SourceLineNumber sourceLineNumbers, XAttribute attribute); + string GetAttributeBundleVariableNameValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, BundleVariableNameRule nameRule = BundleVariableNameRule.CanBeWellKnown | BundleVariableNameRule.CanHaveReservedPrefix); /// /// Get a guid attribute value and displays an error for an illegal guid value. diff --git a/src/burn/test/BurnUnitTest/VariableTest.cpp b/src/burn/test/BurnUnitTest/VariableTest.cpp index f864307c..8ee6e179 100644 --- a/src/burn/test/BurnUnitTest/VariableTest.cpp +++ b/src/burn/test/BurnUnitTest/VariableTest.cpp @@ -162,6 +162,39 @@ namespace Bootstrapper } } + [Fact] + void VariablesSetCustomWixVariableTest() + { + HRESULT hr = S_OK; + IXMLDOMElement* pixeBundle = NULL; + BURN_VARIABLES variables = { }; + + try + { + LPCWSTR wzDocument = + L"" + L" " + L""; + + hr = VariableInitialize(&variables); + TestThrowOnFailure(hr, L"Failed to initialize variables."); + + // load XML document + LoadBundleXmlHelper(wzDocument, &pixeBundle); + + hr = VariablesParseFromXml(&variables, pixeBundle); + NativeAssert::Succeeded(hr, "Failed to parse variables from XML."); + + hr = VariableSetString(&variables, L"WixCustomVariable", L"something", FALSE, FALSE); + NativeAssert::Succeeded(hr, "Failed to set 'WixCustomVariable' variable."); + } + finally + { + ReleaseObject(pixeBundle); + VariablesUninitialize(&variables); + } + } + [Fact] void VariablesFormatTest() { diff --git a/src/ext/Util/test/WixToolsetTest.Util/TestData/BundleWithSearches/BundleUsingDiscouragedVariableNames.wxs b/src/ext/Util/test/WixToolsetTest.Util/TestData/BundleWithSearches/BundleUsingDiscouragedVariableNames.wxs new file mode 100644 index 00000000..68f46af8 --- /dev/null +++ b/src/ext/Util/test/WixToolsetTest.Util/TestData/BundleWithSearches/BundleUsingDiscouragedVariableNames.wxs @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs b/src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs index 39b792b7..24641fce 100644 --- a/src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs +++ b/src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs @@ -296,6 +296,53 @@ namespace WixToolsetTest.Util } } + [Fact] + public void CanBuildBundleWithWarningsWithSearchesUsingDiscouragedVariableNames() + { + var folder = TestData.Get("TestData", "BundleWithSearches"); + var rootFolder = TestData.Get(); + var wixext = Path.Combine(rootFolder, "WixToolset.Util.wixext.dll"); + + using (var fs = new DisposableFileSystem()) + { + var baseFolder = fs.GetFolder(); + var intermediateFolder = Path.Combine(baseFolder, "obj"); + var bundlePath = Path.Combine(baseFolder, @"bin\test.exe"); + var baFolderPath = Path.Combine(baseFolder, "ba"); + var extractFolderPath = Path.Combine(baseFolder, "extract"); + + var result = WixRunner.Execute(false, new[] + { + "build", + Path.Combine(folder, "BundleUsingDiscouragedVariableNames.wxs"), + "-ext", wixext, + "-loc", Path.Combine(folder, "Bundle.en-us.wxl"), + "-bindpath", Path.Combine(folder, "data"), + "-intermediateFolder", intermediateFolder, + "-o", bundlePath, + }); + + var messages = result.Messages.Select(m => m.ToString()).ToList(); + messages.Sort(); + + WixAssert.CompareLineByLine(new[] + { + "The *Search/@Variable attribute's value begins with the reserved prefix 'Wix'. Some prefixes are reserved by the WiX toolset for well-known values. Change your attribute's value to not begin with the same prefix.", + }, messages.ToArray()); + + result.AssertSuccess(); + + var extractResult = BundleExtractor.ExtractBAContainer(null, bundlePath, baFolderPath, extractFolderPath); + extractResult.AssertSuccess(); + + var utilSearches = extractResult.GetManifestTestXmlLines("/burn:BurnManifest/*[self::burn:ExtensionSearch or self::burn:DirectorySearch or self::burn:FileSearch or self::burn:MsiProductSearch or self::burn:RegistrySearch]"); + WixAssert.CompareLineByLine(new[] + { + @"", + }, utilSearches); + } + } + [Fact] public void CannotBuildBundleWithSearchesUsingBuiltinVariableNames() { @@ -307,7 +354,6 @@ namespace WixToolsetTest.Util { var baseFolder = fs.GetFolder(); var intermediateFolder = Path.Combine(baseFolder, "obj"); - var bundlePath = Path.Combine(baseFolder, "bin", "test.exe"); var result = WixRunner.Execute(new[] { @@ -317,7 +363,7 @@ namespace WixToolsetTest.Util "-loc", Path.Combine(folder, "Bundle.en-us.wxl"), "-bindpath", Path.Combine(folder, "data"), "-intermediateFolder", intermediateFolder, - "-o", bundlePath + "-o", "bundle.wixlib", }); var messages = result.Messages.Select(m => m.ToString()).ToList(); @@ -325,13 +371,12 @@ namespace WixToolsetTest.Util WixAssert.CompareLineByLine(new[] { - "The DirectorySearch/@Variable attribute's value, 'InstallerName', is one of the illegal options: 'AdminToolsFolder', 'AppDataFolder', 'CommonAppDataFolder', 'CommonFiles64Folder', 'CommonFilesFolder', 'CompatibilityMode', 'Date', 'DesktopFolder', 'FavoritesFolder', 'FontsFolder', 'InstallerName', 'InstallerVersion', 'LocalAppDataFolder', 'LogonUser', 'MyPicturesFolder', 'NativeMachine', 'NTProductType', 'NTSuiteBackOffice', 'NTSuiteDataCenter', 'NTSuiteEnterprise', 'NTSuitePersonal', 'NTSuiteSmallBusiness', 'NTSuiteSmallBusinessRestricted', 'NTSuiteWebServer', 'PersonalFolder', 'Privileged', 'ProgramFiles64Folder', 'ProgramFiles6432Folder', 'ProgramFilesFolder', 'ProgramMenuFolder', 'RebootPending', 'SendToFolder', 'ServicePackLevel', 'StartMenuFolder', 'StartupFolder', 'System64Folder', 'SystemFolder', 'TempFolder', 'TemplateFolder', 'TerminalServer', 'UserLanguageID', 'UserUILanguageID', 'VersionMsi', 'VersionNT', 'VersionNT64', 'WindowsFolder', 'WindowsVolume', 'WixBundleAction', 'WixBundleCommandLineAction', 'WixBundleForcedRestartPackage', 'WixBundleElevated', 'WixBundleInstalled', 'WixBundleProviderKey', 'WixBundleTag', or 'WixBundleVersion'.", - "The FileSearch/@Variable attribute's value, 'NativeMachine', is one of the illegal options: 'AdminToolsFolder', 'AppDataFolder', 'CommonAppDataFolder', 'CommonFiles64Folder', 'CommonFilesFolder', 'CompatibilityMode', 'Date', 'DesktopFolder', 'FavoritesFolder', 'FontsFolder', 'InstallerName', 'InstallerVersion', 'LocalAppDataFolder', 'LogonUser', 'MyPicturesFolder', 'NativeMachine', 'NTProductType', 'NTSuiteBackOffice', 'NTSuiteDataCenter', 'NTSuiteEnterprise', 'NTSuitePersonal', 'NTSuiteSmallBusiness', 'NTSuiteSmallBusinessRestricted', 'NTSuiteWebServer', 'PersonalFolder', 'Privileged', 'ProgramFiles64Folder', 'ProgramFiles6432Folder', 'ProgramFilesFolder', 'ProgramMenuFolder', 'RebootPending', 'SendToFolder', 'ServicePackLevel', 'StartMenuFolder', 'StartupFolder', 'System64Folder', 'SystemFolder', 'TempFolder', 'TemplateFolder', 'TerminalServer', 'UserLanguageID', 'UserUILanguageID', 'VersionMsi', 'VersionNT', 'VersionNT64', 'WindowsFolder', 'WindowsVolume', 'WixBundleAction', 'WixBundleCommandLineAction', 'WixBundleForcedRestartPackage', 'WixBundleElevated', 'WixBundleInstalled', 'WixBundleProviderKey', 'WixBundleTag', or 'WixBundleVersion'.", - "The ProductSearch/@Variable attribute's value, 'Date', is one of the illegal options: 'AdminToolsFolder', 'AppDataFolder', 'CommonAppDataFolder', 'CommonFiles64Folder', 'CommonFilesFolder', 'CompatibilityMode', 'Date', 'DesktopFolder', 'FavoritesFolder', 'FontsFolder', 'InstallerName', 'InstallerVersion', 'LocalAppDataFolder', 'LogonUser', 'MyPicturesFolder', 'NativeMachine', 'NTProductType', 'NTSuiteBackOffice', 'NTSuiteDataCenter', 'NTSuiteEnterprise', 'NTSuitePersonal', 'NTSuiteSmallBusiness', 'NTSuiteSmallBusinessRestricted', 'NTSuiteWebServer', 'PersonalFolder', 'Privileged', 'ProgramFiles64Folder', 'ProgramFiles6432Folder', 'ProgramFilesFolder', 'ProgramMenuFolder', 'RebootPending', 'SendToFolder', 'ServicePackLevel', 'StartMenuFolder', 'StartupFolder', 'System64Folder', 'SystemFolder', 'TempFolder', 'TemplateFolder', 'TerminalServer', 'UserLanguageID', 'UserUILanguageID', 'VersionMsi', 'VersionNT', 'VersionNT64', 'WindowsFolder', 'WindowsVolume', 'WixBundleAction', 'WixBundleCommandLineAction', 'WixBundleForcedRestartPackage', 'WixBundleElevated', 'WixBundleInstalled', 'WixBundleProviderKey', 'WixBundleTag', or 'WixBundleVersion'.", - "The RegistrySearch/@Variable attribute's value begins with the reserved prefix 'Wix'. Some prefixes are reserved by the WiX toolset for well-known values. Change your attribute's value to not begin with the same prefix.", - "The RegistrySearch/@Variable attribute's value, 'VersionNT64', is one of the illegal options: 'AdminToolsFolder', 'AppDataFolder', 'CommonAppDataFolder', 'CommonFiles64Folder', 'CommonFilesFolder', 'CompatibilityMode', 'Date', 'DesktopFolder', 'FavoritesFolder', 'FontsFolder', 'InstallerName', 'InstallerVersion', 'LocalAppDataFolder', 'LogonUser', 'MyPicturesFolder', 'NativeMachine', 'NTProductType', 'NTSuiteBackOffice', 'NTSuiteDataCenter', 'NTSuiteEnterprise', 'NTSuitePersonal', 'NTSuiteSmallBusiness', 'NTSuiteSmallBusinessRestricted', 'NTSuiteWebServer', 'PersonalFolder', 'Privileged', 'ProgramFiles64Folder', 'ProgramFiles6432Folder', 'ProgramFilesFolder', 'ProgramMenuFolder', 'RebootPending', 'SendToFolder', 'ServicePackLevel', 'StartMenuFolder', 'StartupFolder', 'System64Folder', 'SystemFolder', 'TempFolder', 'TemplateFolder', 'TerminalServer', 'UserLanguageID', 'UserUILanguageID', 'VersionMsi', 'VersionNT', 'VersionNT64', 'WindowsFolder', 'WindowsVolume', 'WixBundleAction', 'WixBundleCommandLineAction', 'WixBundleForcedRestartPackage', 'WixBundleElevated', 'WixBundleInstalled', 'WixBundleProviderKey', 'WixBundleTag', or 'WixBundleVersion'.", - "The RegistrySearch/@Variable attribute's value, 'WixBundleAction', is one of the illegal options: 'AdminToolsFolder', 'AppDataFolder', 'CommonAppDataFolder', 'CommonFiles64Folder', 'CommonFilesFolder', 'CompatibilityMode', 'Date', 'DesktopFolder', 'FavoritesFolder', 'FontsFolder', 'InstallerName', 'InstallerVersion', 'LocalAppDataFolder', 'LogonUser', 'MyPicturesFolder', 'NativeMachine', 'NTProductType', 'NTSuiteBackOffice', 'NTSuiteDataCenter', 'NTSuiteEnterprise', 'NTSuitePersonal', 'NTSuiteSmallBusiness', 'NTSuiteSmallBusinessRestricted', 'NTSuiteWebServer', 'PersonalFolder', 'Privileged', 'ProgramFiles64Folder', 'ProgramFiles6432Folder', 'ProgramFilesFolder', 'ProgramMenuFolder', 'RebootPending', 'SendToFolder', 'ServicePackLevel', 'StartMenuFolder', 'StartupFolder', 'System64Folder', 'SystemFolder', 'TempFolder', 'TemplateFolder', 'TerminalServer', 'UserLanguageID', 'UserUILanguageID', 'VersionMsi', 'VersionNT', 'VersionNT64', 'WindowsFolder', 'WindowsVolume', 'WixBundleAction', 'WixBundleCommandLineAction', 'WixBundleForcedRestartPackage', 'WixBundleElevated', 'WixBundleInstalled', 'WixBundleProviderKey', 'WixBundleTag', or 'WixBundleVersion'.", - "The WindowsFeatureSearch/@Variable attribute's value, 'NTProductType', is one of the illegal options: 'AdminToolsFolder', 'AppDataFolder', 'CommonAppDataFolder', 'CommonFiles64Folder', 'CommonFilesFolder', 'CompatibilityMode', 'Date', 'DesktopFolder', 'FavoritesFolder', 'FontsFolder', 'InstallerName', 'InstallerVersion', 'LocalAppDataFolder', 'LogonUser', 'MyPicturesFolder', 'NativeMachine', 'NTProductType', 'NTSuiteBackOffice', 'NTSuiteDataCenter', 'NTSuiteEnterprise', 'NTSuitePersonal', 'NTSuiteSmallBusiness', 'NTSuiteSmallBusinessRestricted', 'NTSuiteWebServer', 'PersonalFolder', 'Privileged', 'ProgramFiles64Folder', 'ProgramFiles6432Folder', 'ProgramFilesFolder', 'ProgramMenuFolder', 'RebootPending', 'SendToFolder', 'ServicePackLevel', 'StartMenuFolder', 'StartupFolder', 'System64Folder', 'SystemFolder', 'TempFolder', 'TemplateFolder', 'TerminalServer', 'UserLanguageID', 'UserUILanguageID', 'VersionMsi', 'VersionNT', 'VersionNT64', 'WindowsFolder', 'WindowsVolume', 'WixBundleAction', 'WixBundleCommandLineAction', 'WixBundleForcedRestartPackage', 'WixBundleElevated', 'WixBundleInstalled', 'WixBundleProviderKey', 'WixBundleTag', or 'WixBundleVersion'.", + "The DirectorySearch/@Variable attribute's value, 'InstallerName', is one of the illegal options: 'AdminToolsFolder', 'AppDataFolder', 'CommonAppDataFolder', 'CommonFiles64Folder', 'CommonFiles6432Folder', 'CommonFilesFolder', 'CompatibilityMode', 'ComputerName', 'Date', 'DesktopFolder', 'FavoritesFolder', 'FontsFolder', 'InstallerName', 'InstallerVersion', 'LocalAppDataFolder', 'LogonUser', 'MyPicturesFolder', 'NativeMachine', 'NTProductType', 'NTSuiteBackOffice', 'NTSuiteDataCenter', 'NTSuiteEnterprise', 'NTSuitePersonal', 'NTSuiteSmallBusiness', 'NTSuiteSmallBusinessRestricted', 'NTSuiteWebServer', 'PersonalFolder', 'Privileged', 'ProcessorArchitecture', 'ProgramFiles64Folder', 'ProgramFiles6432Folder', 'ProgramFilesFolder', 'ProgramMenuFolder', 'RebootPending', 'SendToFolder', 'ServicePackLevel', 'StartMenuFolder', 'StartupFolder', 'System64Folder', 'SystemFolder', 'SystemLanguageID', 'TempFolder', 'TemplateFolder', 'TerminalServer', 'UserLanguageID', 'UserUILanguageID', 'VersionMsi', 'VersionNT', 'VersionNT64', 'WindowsBuildNumber', 'WindowsFolder', 'WindowsVolume', 'WixBundleAction', 'WixBundleActiveParent', 'WixBundleCommandLineAction', 'WixBundleElevated', 'WixBundleExecutePackageAction', 'WixBundleExecutePackageCacheFolder', 'WixBundleForcedRestartPackage', 'WixBundleInstalled', 'WixBundleProviderKey', 'WixBundleSourceProcessFolder', 'WixBundleSourceProcessPath', 'WixBundleTag', 'WixBundleUILevel', or 'WixBundleVersion'.", + "The FileSearch/@Variable attribute's value, 'NativeMachine', is one of the illegal options: 'AdminToolsFolder', 'AppDataFolder', 'CommonAppDataFolder', 'CommonFiles64Folder', 'CommonFiles6432Folder', 'CommonFilesFolder', 'CompatibilityMode', 'ComputerName', 'Date', 'DesktopFolder', 'FavoritesFolder', 'FontsFolder', 'InstallerName', 'InstallerVersion', 'LocalAppDataFolder', 'LogonUser', 'MyPicturesFolder', 'NativeMachine', 'NTProductType', 'NTSuiteBackOffice', 'NTSuiteDataCenter', 'NTSuiteEnterprise', 'NTSuitePersonal', 'NTSuiteSmallBusiness', 'NTSuiteSmallBusinessRestricted', 'NTSuiteWebServer', 'PersonalFolder', 'Privileged', 'ProcessorArchitecture', 'ProgramFiles64Folder', 'ProgramFiles6432Folder', 'ProgramFilesFolder', 'ProgramMenuFolder', 'RebootPending', 'SendToFolder', 'ServicePackLevel', 'StartMenuFolder', 'StartupFolder', 'System64Folder', 'SystemFolder', 'SystemLanguageID', 'TempFolder', 'TemplateFolder', 'TerminalServer', 'UserLanguageID', 'UserUILanguageID', 'VersionMsi', 'VersionNT', 'VersionNT64', 'WindowsBuildNumber', 'WindowsFolder', 'WindowsVolume', 'WixBundleAction', 'WixBundleActiveParent', 'WixBundleCommandLineAction', 'WixBundleElevated', 'WixBundleExecutePackageAction', 'WixBundleExecutePackageCacheFolder', 'WixBundleForcedRestartPackage', 'WixBundleInstalled', 'WixBundleProviderKey', 'WixBundleSourceProcessFolder', 'WixBundleSourceProcessPath', 'WixBundleTag', 'WixBundleUILevel', or 'WixBundleVersion'.", + "The ProductSearch/@Variable attribute's value, 'Date', is one of the illegal options: 'AdminToolsFolder', 'AppDataFolder', 'CommonAppDataFolder', 'CommonFiles64Folder', 'CommonFiles6432Folder', 'CommonFilesFolder', 'CompatibilityMode', 'ComputerName', 'Date', 'DesktopFolder', 'FavoritesFolder', 'FontsFolder', 'InstallerName', 'InstallerVersion', 'LocalAppDataFolder', 'LogonUser', 'MyPicturesFolder', 'NativeMachine', 'NTProductType', 'NTSuiteBackOffice', 'NTSuiteDataCenter', 'NTSuiteEnterprise', 'NTSuitePersonal', 'NTSuiteSmallBusiness', 'NTSuiteSmallBusinessRestricted', 'NTSuiteWebServer', 'PersonalFolder', 'Privileged', 'ProcessorArchitecture', 'ProgramFiles64Folder', 'ProgramFiles6432Folder', 'ProgramFilesFolder', 'ProgramMenuFolder', 'RebootPending', 'SendToFolder', 'ServicePackLevel', 'StartMenuFolder', 'StartupFolder', 'System64Folder', 'SystemFolder', 'SystemLanguageID', 'TempFolder', 'TemplateFolder', 'TerminalServer', 'UserLanguageID', 'UserUILanguageID', 'VersionMsi', 'VersionNT', 'VersionNT64', 'WindowsBuildNumber', 'WindowsFolder', 'WindowsVolume', 'WixBundleAction', 'WixBundleActiveParent', 'WixBundleCommandLineAction', 'WixBundleElevated', 'WixBundleExecutePackageAction', 'WixBundleExecutePackageCacheFolder', 'WixBundleForcedRestartPackage', 'WixBundleInstalled', 'WixBundleProviderKey', 'WixBundleSourceProcessFolder', 'WixBundleSourceProcessPath', 'WixBundleTag', 'WixBundleUILevel', or 'WixBundleVersion'.", + "The RegistrySearch/@Variable attribute's value, 'VersionNT64', is one of the illegal options: 'AdminToolsFolder', 'AppDataFolder', 'CommonAppDataFolder', 'CommonFiles64Folder', 'CommonFiles6432Folder', 'CommonFilesFolder', 'CompatibilityMode', 'ComputerName', 'Date', 'DesktopFolder', 'FavoritesFolder', 'FontsFolder', 'InstallerName', 'InstallerVersion', 'LocalAppDataFolder', 'LogonUser', 'MyPicturesFolder', 'NativeMachine', 'NTProductType', 'NTSuiteBackOffice', 'NTSuiteDataCenter', 'NTSuiteEnterprise', 'NTSuitePersonal', 'NTSuiteSmallBusiness', 'NTSuiteSmallBusinessRestricted', 'NTSuiteWebServer', 'PersonalFolder', 'Privileged', 'ProcessorArchitecture', 'ProgramFiles64Folder', 'ProgramFiles6432Folder', 'ProgramFilesFolder', 'ProgramMenuFolder', 'RebootPending', 'SendToFolder', 'ServicePackLevel', 'StartMenuFolder', 'StartupFolder', 'System64Folder', 'SystemFolder', 'SystemLanguageID', 'TempFolder', 'TemplateFolder', 'TerminalServer', 'UserLanguageID', 'UserUILanguageID', 'VersionMsi', 'VersionNT', 'VersionNT64', 'WindowsBuildNumber', 'WindowsFolder', 'WindowsVolume', 'WixBundleAction', 'WixBundleActiveParent', 'WixBundleCommandLineAction', 'WixBundleElevated', 'WixBundleExecutePackageAction', 'WixBundleExecutePackageCacheFolder', 'WixBundleForcedRestartPackage', 'WixBundleInstalled', 'WixBundleProviderKey', 'WixBundleSourceProcessFolder', 'WixBundleSourceProcessPath', 'WixBundleTag', 'WixBundleUILevel', or 'WixBundleVersion'.", + "The RegistrySearch/@Variable attribute's value, 'WixBundleAction', is one of the illegal options: 'AdminToolsFolder', 'AppDataFolder', 'CommonAppDataFolder', 'CommonFiles64Folder', 'CommonFiles6432Folder', 'CommonFilesFolder', 'CompatibilityMode', 'ComputerName', 'Date', 'DesktopFolder', 'FavoritesFolder', 'FontsFolder', 'InstallerName', 'InstallerVersion', 'LocalAppDataFolder', 'LogonUser', 'MyPicturesFolder', 'NativeMachine', 'NTProductType', 'NTSuiteBackOffice', 'NTSuiteDataCenter', 'NTSuiteEnterprise', 'NTSuitePersonal', 'NTSuiteSmallBusiness', 'NTSuiteSmallBusinessRestricted', 'NTSuiteWebServer', 'PersonalFolder', 'Privileged', 'ProcessorArchitecture', 'ProgramFiles64Folder', 'ProgramFiles6432Folder', 'ProgramFilesFolder', 'ProgramMenuFolder', 'RebootPending', 'SendToFolder', 'ServicePackLevel', 'StartMenuFolder', 'StartupFolder', 'System64Folder', 'SystemFolder', 'SystemLanguageID', 'TempFolder', 'TemplateFolder', 'TerminalServer', 'UserLanguageID', 'UserUILanguageID', 'VersionMsi', 'VersionNT', 'VersionNT64', 'WindowsBuildNumber', 'WindowsFolder', 'WindowsVolume', 'WixBundleAction', 'WixBundleActiveParent', 'WixBundleCommandLineAction', 'WixBundleElevated', 'WixBundleExecutePackageAction', 'WixBundleExecutePackageCacheFolder', 'WixBundleForcedRestartPackage', 'WixBundleInstalled', 'WixBundleProviderKey', 'WixBundleSourceProcessFolder', 'WixBundleSourceProcessPath', 'WixBundleTag', 'WixBundleUILevel', or 'WixBundleVersion'.", + "The WindowsFeatureSearch/@Variable attribute's value, 'NTProductType', is one of the illegal options: 'AdminToolsFolder', 'AppDataFolder', 'CommonAppDataFolder', 'CommonFiles64Folder', 'CommonFiles6432Folder', 'CommonFilesFolder', 'CompatibilityMode', 'ComputerName', 'Date', 'DesktopFolder', 'FavoritesFolder', 'FontsFolder', 'InstallerName', 'InstallerVersion', 'LocalAppDataFolder', 'LogonUser', 'MyPicturesFolder', 'NativeMachine', 'NTProductType', 'NTSuiteBackOffice', 'NTSuiteDataCenter', 'NTSuiteEnterprise', 'NTSuitePersonal', 'NTSuiteSmallBusiness', 'NTSuiteSmallBusinessRestricted', 'NTSuiteWebServer', 'PersonalFolder', 'Privileged', 'ProcessorArchitecture', 'ProgramFiles64Folder', 'ProgramFiles6432Folder', 'ProgramFilesFolder', 'ProgramMenuFolder', 'RebootPending', 'SendToFolder', 'ServicePackLevel', 'StartMenuFolder', 'StartupFolder', 'System64Folder', 'SystemFolder', 'SystemLanguageID', 'TempFolder', 'TemplateFolder', 'TerminalServer', 'UserLanguageID', 'UserUILanguageID', 'VersionMsi', 'VersionNT', 'VersionNT64', 'WindowsBuildNumber', 'WindowsFolder', 'WindowsVolume', 'WixBundleAction', 'WixBundleActiveParent', 'WixBundleCommandLineAction', 'WixBundleElevated', 'WixBundleExecutePackageAction', 'WixBundleExecutePackageCacheFolder', 'WixBundleForcedRestartPackage', 'WixBundleInstalled', 'WixBundleProviderKey', 'WixBundleSourceProcessFolder', 'WixBundleSourceProcessPath', 'WixBundleTag', 'WixBundleUILevel', or 'WixBundleVersion'.", }, messages.ToArray()); } } diff --git a/src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs index a37e874c..49a25c0a 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs @@ -163,7 +163,7 @@ namespace WixToolset.Core.Burn.Bundles private void ValidateSearch(WixSearchSymbol symbol) { - this.BackendHelper.ValidateBundleVariableName(symbol.SourceLineNumbers, "*Search", "Variable", symbol.Variable, allowBuiltIn: false); + this.BackendHelper.ValidateBundleVariableNameTarget(symbol.SourceLineNumbers, "*Search", "Variable", symbol.Variable); if (symbol.Condition != null) { @@ -173,7 +173,7 @@ namespace WixToolset.Core.Burn.Bundles private void ValidateVariable(WixBundleVariableSymbol symbol) { - this.BackendHelper.ValidateBundleVariableName(symbol.SourceLineNumbers, "Variable", "Name", symbol.Id.Id, allowBuiltIn: false); + this.BackendHelper.ValidateBundleVariableNameDeclaration(symbol.SourceLineNumbers, "Variable", "Name", symbol.Id.Id); } } } diff --git a/src/wix/WixToolset.Core.Burn/ExtensibilityServices/BurnBackendHelper.cs b/src/wix/WixToolset.Core.Burn/ExtensibilityServices/BurnBackendHelper.cs index 58fdeca5..93e7fc20 100644 --- a/src/wix/WixToolset.Core.Burn/ExtensibilityServices/BurnBackendHelper.cs +++ b/src/wix/WixToolset.Core.Burn/ExtensibilityServices/BurnBackendHelper.cs @@ -190,9 +190,19 @@ namespace WixToolset.Core.Burn.ExtensibilityServices return this.bundleValidator.ValidateBundleMsiPropertyName(sourceLineNumbers, elementName, attributeName, propertyName); } - public bool ValidateBundleVariableName(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName, bool allowBuiltIn) + public bool ValidateBundleVariableNameDeclaration(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName) { - return this.bundleValidator.ValidateBundleVariableName(sourceLineNumbers, elementName, attributeName, variableName, allowBuiltIn); + return this.bundleValidator.ValidateBundleVariableNameDeclaration(sourceLineNumbers, elementName, attributeName, variableName); + } + + public bool ValidateBundleVariableNameValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName, BundleVariableNameRule nameRule) + { + return this.bundleValidator.ValidateBundleVariableNameValue(sourceLineNumbers, elementName, attributeName, variableName, nameRule); + } + + public bool ValidateBundleVariableNameTarget(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName) + { + return this.bundleValidator.ValidateBundleVariableNameTarget(sourceLineNumbers, elementName, attributeName, variableName); } public bool ValidateBundleCondition(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string condition, BundleConditionPhase phase) diff --git a/src/wix/WixToolset.Core/CompilerWarnings.cs b/src/wix/WixToolset.Core/CompilerWarnings.cs index 7fca29bb..ed221c3e 100644 --- a/src/wix/WixToolset.Core/CompilerWarnings.cs +++ b/src/wix/WixToolset.Core/CompilerWarnings.cs @@ -36,11 +36,21 @@ namespace WixToolset.Core return Message(sourceLineNumbers, Ids.ProvidesKeyNotFound, "The provider key with identifier {0} was not found in the Wix4DependencyProvider table. Related registry rows will not be removed from authoring.", id); } + public static Message ReadonlyLogVariableTarget(SourceLineNumber sourceLineNumbers, string element, string attribute, string name) + { + return Message(sourceLineNumbers, Ids.ReadonlyLogVariableTarget, "The {0}/@{1} attribute's value references the well-known log Variable '{2}' to change its value. This variable is set by the engine and is intended to be read-only. Change your attribute's value to reference a custom variable.", element, attribute, name); + } + public static Message RequiresKeyNotFound(SourceLineNumber sourceLineNumbers, string id) { return Message(sourceLineNumbers, Ids.RequiresKeyNotFound, "The dependency key with identifier {0} was not found in the Wix4Dependency table. Related registry rows will not be removed from authoring.", id); } + public static Message ReservedBurnNamespaceWarning(SourceLineNumber sourceLineNumbers, string element, string attribute, string prefix) + { + return Message(sourceLineNumbers, Ids.ReservedBurnNamespaceWarning, "The {0}/@{1} attribute's value begins with the reserved prefix '{2}'. Some prefixes are reserved by the WiX toolset for well-known values. Change your attribute's value to not begin with the same prefix.", element, attribute, prefix); + } + public static Message Win64Component(SourceLineNumber sourceLineNumbers, string componentId) { return Message(sourceLineNumbers, Ids.Win64Component, "The Provides element should not be authored in the 64-bit component with identifier {0}. The dependency feature may not work if installing this package on 64-bit Windows operating systems prior to Windows 7 and Windows Server 2008 R2. Set the Component/@Bitness attribute to \"always32\" to ensure the dependency feature works correctly on legacy operating systems.", componentId); @@ -60,6 +70,8 @@ namespace WixToolset.Core Win64Component = 5435, DirectoryRefStandardDirectoryDeprecated = 5436, DefiningStandardDirectoryDeprecated = 5437, + ReadonlyLogVariableTarget = 5438, + ReservedBurnNamespaceWarning = 5439, } // 5400-5499 and 6600-6699 were the ranges for Dependency and Tag which are now in Core between CompilerWarnings and CompilerErrors. } } diff --git a/src/wix/WixToolset.Core/ExtensibilityServices/BundleValidator.cs b/src/wix/WixToolset.Core/ExtensibilityServices/BundleValidator.cs index 8717a3b9..838ffb88 100644 --- a/src/wix/WixToolset.Core/ExtensibilityServices/BundleValidator.cs +++ b/src/wix/WixToolset.Core/ExtensibilityServices/BundleValidator.cs @@ -109,6 +109,21 @@ namespace WixToolset.Core.ExtensibilityServices "WixBundleVersion", }); + // Well-known variables (from burn\engine\variable.cpp, "vrgWellKnownVariables", around line 304) + private static readonly List WellKnownBundleVariables = new List( + new string[] { + "WixBundleInProgressName", + "WixBundleLastUsedSource", + "WixBundleLayoutDirectory", + "WixBundleLog", + "WixBundleLog_*", + "WixBundleRollbackLog_*", + "WixBundleManufacturer", + "WixBundleName", + "WixBundleOriginalSource", + "WixBundleOriginalSourceFolder", + }); + private static readonly List DisallowedMsiProperties = new List( new string[] { "ACTION", @@ -156,7 +171,7 @@ namespace WixToolset.Core.ExtensibilityServices return relativePath; } - public bool ValidateBundleVariableName(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName, bool allowBuiltIn) + public bool ValidateBundleVariableNameDeclaration(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName) { if (String.IsNullOrEmpty(variableName)) { @@ -170,14 +185,14 @@ namespace WixToolset.Core.ExtensibilityServices return false; } - else if (!allowBuiltIn && BuiltinBundleVariables.Contains(variableName)) + else if (BuiltinBundleVariables.Contains(variableName)) { var illegalValues = CreateValueList(ValueListKind.Or, BuiltinBundleVariables); this.Messaging.Write(ErrorMessages.IllegalAttributeValueWithIllegalList(sourceLineNumbers, elementName, attributeName, variableName, illegalValues)); return false; } - else if (!allowBuiltIn && variableName.StartsWith("Wix", StringComparison.OrdinalIgnoreCase)) + else if (variableName.StartsWith("Wix", StringComparison.OrdinalIgnoreCase)) { this.Messaging.Write(ErrorMessages.ReservedBurnNamespaceViolation(sourceLineNumbers, elementName, attributeName, "Wix")); @@ -189,6 +204,105 @@ namespace WixToolset.Core.ExtensibilityServices } } + public bool ValidateBundleVariableNameValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName, BundleVariableNameRule nameRule) + { + if (String.IsNullOrEmpty(variableName)) + { + this.Messaging.Write(ErrorMessages.IllegalEmptyAttributeValue(sourceLineNumbers, elementName, attributeName)); + + return false; + } + else if (!Common.IsBundleVariableName(variableName)) + { + this.Messaging.Write(CompilerErrors.IllegalBundleVariableName(sourceLineNumbers, elementName, attributeName, variableName)); + + return false; + } + else if (BuiltinBundleVariables.Contains(variableName)) + { + var allowed = nameRule.HasFlag(BundleVariableNameRule.CanBeBuiltIn); + if (!allowed) + { + var illegalValues = CreateValueList(ValueListKind.Or, BuiltinBundleVariables); + this.Messaging.Write(ErrorMessages.IllegalAttributeValueWithIllegalList(sourceLineNumbers, elementName, attributeName, variableName, illegalValues)); + } + + return allowed; + } + else if (WellKnownBundleVariables.Contains(variableName) || + variableName.StartsWith("WixBundleLog_", StringComparison.OrdinalIgnoreCase) || + variableName.StartsWith("WixBundleRollbackLog_", StringComparison.OrdinalIgnoreCase)) + { + var allowed = nameRule.HasFlag(BundleVariableNameRule.CanBeWellKnown); + if (!allowed) + { + var illegalValues = CreateValueList(ValueListKind.Or, WellKnownBundleVariables); + this.Messaging.Write(ErrorMessages.IllegalAttributeValueWithIllegalList(sourceLineNumbers, elementName, attributeName, variableName, illegalValues)); + } + + return allowed; + } + else if (variableName.StartsWith("Wix", StringComparison.OrdinalIgnoreCase)) + { + var allowed = nameRule.HasFlag(BundleVariableNameRule.CanHaveReservedPrefix); + if (!allowed) + { + this.Messaging.Write(ErrorMessages.ReservedBurnNamespaceViolation(sourceLineNumbers, elementName, attributeName, "Wix")); + } + + return allowed; + } + else + { + return true; + } + } + + public bool ValidateBundleVariableNameTarget(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName) + { + if (String.IsNullOrEmpty(variableName)) + { + this.Messaging.Write(ErrorMessages.IllegalEmptyAttributeValue(sourceLineNumbers, elementName, attributeName)); + + return false; + } + else if (!Common.IsBundleVariableName(variableName)) + { + this.Messaging.Write(CompilerErrors.IllegalBundleVariableName(sourceLineNumbers, elementName, attributeName, variableName)); + + return false; + } + else if (BuiltinBundleVariables.Contains(variableName)) + { + var illegalValues = CreateValueList(ValueListKind.Or, BuiltinBundleVariables); + this.Messaging.Write(ErrorMessages.IllegalAttributeValueWithIllegalList(sourceLineNumbers, elementName, attributeName, variableName, illegalValues)); + + return false; + } + else if (variableName.Equals("WixBundleLog", StringComparison.OrdinalIgnoreCase) || + variableName.StartsWith("WixBundleLog_", StringComparison.OrdinalIgnoreCase) || + variableName.StartsWith("WixBundleRollbackLog_", StringComparison.OrdinalIgnoreCase)) + { + this.Messaging.Write(CompilerWarnings.ReadonlyLogVariableTarget(sourceLineNumbers, elementName, attributeName, variableName)); + + return true; + } + else if (WellKnownBundleVariables.Contains(variableName)) + { + return true; + } + else if (variableName.StartsWith("Wix", StringComparison.OrdinalIgnoreCase)) + { + this.Messaging.Write(CompilerWarnings.ReservedBurnNamespaceWarning(sourceLineNumbers, elementName, attributeName, "Wix")); + + return true; + } + else + { + return true; + } + } + public bool ValidateBundleMsiPropertyName(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string propertyName) { if (String.IsNullOrEmpty(propertyName)) diff --git a/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs b/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs index 31607b02..5f4ac726 100644 --- a/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs +++ b/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs @@ -246,9 +246,9 @@ namespace WixToolset.Core.ExtensibilityServices { this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, elementName, "Variable")); } - else + else if (!this.IsValidLocIdentifier(variable) && !Common.IsValidBinderVariable(variable)) { - this.BundleValidator.ValidateBundleVariableName(sourceLineNumbers, elementName, "Variable", variable, allowBuiltIn: false); + this.BundleValidator.ValidateBundleVariableNameValue(sourceLineNumbers, elementName, "Variable", variable, BundleVariableNameRule.CanBeWellKnown | BundleVariableNameRule.CanHaveReservedPrefix); } section.AddSymbol(new WixSearchSymbol(sourceLineNumbers, id) @@ -322,19 +322,19 @@ namespace WixToolset.Core.ExtensibilityServices if (!String.IsNullOrEmpty(variableId?.Id)) { - this.BundleValidator.ValidateBundleVariableName(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, variableId.Id, allowBuiltIn: false); + this.BundleValidator.ValidateBundleVariableNameDeclaration(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, variableId.Id); } return variableId; } - public string GetAttributeBundleVariableNameValue(SourceLineNumber sourceLineNumbers, XAttribute attribute) + public string GetAttributeBundleVariableNameValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, BundleVariableNameRule nameRule = BundleVariableNameRule.CanBeWellKnown | BundleVariableNameRule.CanHaveReservedPrefix) { var variableName = this.GetAttributeValue(sourceLineNumbers, attribute); - if (!String.IsNullOrEmpty(variableName)) + if (!String.IsNullOrEmpty(variableName) && !this.IsValidLocIdentifier(variableName) && !Common.IsValidBinderVariable(variableName)) { - this.BundleValidator.ValidateBundleVariableName(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, variableName, allowBuiltIn: false); + this.BundleValidator.ValidateBundleVariableNameValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, variableName, nameRule); } return variableName; diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/BadInputFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/BadInputFixture.cs index b09506c0..9c636a8f 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/BadInputFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/BadInputFixture.cs @@ -7,6 +7,7 @@ namespace WixToolsetTest.CoreIntegration using System.Linq; using WixBuildTools.TestSupport; using WixToolset.Core.TestPackage; + using WixToolset.Data; using Xunit; public class BadInputFixture @@ -179,12 +180,11 @@ namespace WixToolsetTest.CoreIntegration WixAssert.CompareLineByLine(new[] { - "The SetVariable/@Variable attribute's value, '!(loc.BuiltinBurnVariableName)', is not a legal bundle variable name. Identifiers may contain ASCII characters A-Z, a-z, digits, or underscores (_). Every identifier must begin with either a letter or an underscore.", "The Variable/@Name attribute was not found; it is required.", "The Variable/@Name attribute's value, '!(loc.BuiltinBurnVariableName)', is not a legal identifier. Identifiers may contain ASCII characters A-Z, a-z, digits, underscores (_), or periods (.). Every identifier must begin with either a letter or an underscore.", }, messages.ToArray()); - Assert.Equal(6603, result.ExitCode); + Assert.Equal(10, result.ExitCode); } } @@ -212,7 +212,6 @@ namespace WixToolsetTest.CoreIntegration WixAssert.CompareLineByLine(new[] { - "The SetVariable/@Variable attribute's value begins with the reserved prefix 'Wix'. Some prefixes are reserved by the WiX toolset for well-known values. Change your attribute's value to not begin with the same prefix.", "The SetVariable/@Variable attribute's value, 'WixBundleInstalled', is one of the illegal options: 'AdminToolsFolder', 'AppDataFolder', 'CommonAppDataFolder', 'CommonFiles64Folder', 'CommonFiles6432Folder', 'CommonFilesFolder', 'CompatibilityMode', 'ComputerName', 'Date', 'DesktopFolder', 'FavoritesFolder', 'FontsFolder', 'InstallerName', 'InstallerVersion', 'LocalAppDataFolder', 'LogonUser', 'MyPicturesFolder', 'NativeMachine', 'NTProductType', 'NTSuiteBackOffice', 'NTSuiteDataCenter', 'NTSuiteEnterprise', 'NTSuitePersonal', 'NTSuiteSmallBusiness', 'NTSuiteSmallBusinessRestricted', 'NTSuiteWebServer', 'PersonalFolder', 'Privileged', 'ProcessorArchitecture', 'ProgramFiles64Folder', 'ProgramFiles6432Folder', 'ProgramFilesFolder', 'ProgramMenuFolder', 'RebootPending', 'SendToFolder', 'ServicePackLevel', 'StartMenuFolder', 'StartupFolder', 'System64Folder', 'SystemFolder', 'SystemLanguageID', 'TempFolder', 'TemplateFolder', 'TerminalServer', 'UserLanguageID', 'UserUILanguageID', 'VersionMsi', 'VersionNT', 'VersionNT64', 'WindowsBuildNumber', 'WindowsFolder', 'WindowsVolume', 'WixBundleAction', 'WixBundleActiveParent', 'WixBundleCommandLineAction', 'WixBundleElevated', 'WixBundleExecutePackageAction', 'WixBundleExecutePackageCacheFolder', 'WixBundleForcedRestartPackage', 'WixBundleInstalled', 'WixBundleProviderKey', 'WixBundleSourceProcessFolder', 'WixBundleSourceProcessPath', 'WixBundleTag', 'WixBundleUILevel', or 'WixBundleVersion'.", "The Variable/@Name attribute's value begins with the reserved prefix 'Wix'. Some prefixes are reserved by the WiX toolset for well-known values. Change your attribute's value to not begin with the same prefix.", "The Variable/@Name attribute's value, 'AppDataFolder', is one of the illegal options: 'AdminToolsFolder', 'AppDataFolder', 'CommonAppDataFolder', 'CommonFiles64Folder', 'CommonFiles6432Folder', 'CommonFilesFolder', 'CompatibilityMode', 'ComputerName', 'Date', 'DesktopFolder', 'FavoritesFolder', 'FontsFolder', 'InstallerName', 'InstallerVersion', 'LocalAppDataFolder', 'LogonUser', 'MyPicturesFolder', 'NativeMachine', 'NTProductType', 'NTSuiteBackOffice', 'NTSuiteDataCenter', 'NTSuiteEnterprise', 'NTSuitePersonal', 'NTSuiteSmallBusiness', 'NTSuiteSmallBusinessRestricted', 'NTSuiteWebServer', 'PersonalFolder', 'Privileged', 'ProcessorArchitecture', 'ProgramFiles64Folder', 'ProgramFiles6432Folder', 'ProgramFilesFolder', 'ProgramMenuFolder', 'RebootPending', 'SendToFolder', 'ServicePackLevel', 'StartMenuFolder', 'StartupFolder', 'System64Folder', 'SystemFolder', 'SystemLanguageID', 'TempFolder', 'TemplateFolder', 'TerminalServer', 'UserLanguageID', 'UserUILanguageID', 'VersionMsi', 'VersionNT', 'VersionNT64', 'WindowsBuildNumber', 'WindowsFolder', 'WindowsVolume', 'WixBundleAction', 'WixBundleActiveParent', 'WixBundleCommandLineAction', 'WixBundleElevated', 'WixBundleExecutePackageAction', 'WixBundleExecutePackageCacheFolder', 'WixBundleForcedRestartPackage', 'WixBundleInstalled', 'WixBundleProviderKey', 'WixBundleSourceProcessFolder', 'WixBundleSourceProcessPath', 'WixBundleTag', 'WixBundleUILevel', or 'WixBundleVersion'.", @@ -232,7 +231,7 @@ namespace WixToolsetTest.CoreIntegration var baseFolder = fs.GetFolder(); var intermediateFolder = Path.Combine(baseFolder, "obj"); - var result = WixRunner.Execute(new[] + var result = WixRunner.Execute(false, new[] { "build", Path.Combine(folder, "BundleWithInvalid", "BundleWithInvalidLocValues.wxs"), @@ -244,21 +243,30 @@ namespace WixToolsetTest.CoreIntegration "-o", Path.Combine(baseFolder, @"bin\test.exe") }); - var messages = result.Messages.Select(m => m.ToString()).ToList(); - messages.Sort(); + var warningMessages = result.Messages.Where(m => m.Level == MessageLevel.Warning).Select(m => m.ToString()).ToList(); + warningMessages.Sort(); WixAssert.CompareLineByLine(new[] { "*Search/@Condition contains the built-in Variable 'WixBundleAction', which is not available when it is evaluated. (Unavailable Variables are: 'WixBundleAction'.). Rewrite the condition to avoid Variables that are never valid during its evaluation.", "Bundle/@Condition contains the built-in Variable 'WixBundleInstalled', which is not available when it is evaluated. (Unavailable Variables are: 'RebootPending', 'WixBundleAction', or 'WixBundleInstalled'.). Rewrite the condition to avoid Variables that are never valid during its evaluation.", "ExePackage/@DetectCondition contains the built-in Variable 'WixBundleAction', which is not available when it is evaluated. (Unavailable Variables are: 'WixBundleAction'.). Rewrite the condition to avoid Variables that are never valid during its evaluation.", + "The *Search/@Variable attribute's value begins with the reserved prefix 'Wix'. Some prefixes are reserved by the WiX toolset for well-known values. Change your attribute's value to not begin with the same prefix.", + "The *Search/@Variable attribute's value references the well-known log Variable 'WixBundleLog' to change its value. This variable is set by the engine and is intended to be read-only. Change your attribute's value to reference a custom variable.", + }, warningMessages.ToArray()); + + var errorMessages = result.Messages.Where(m => m.Level == MessageLevel.Error).Select(m => m.ToString()).ToList(); + errorMessages.Sort(); + + WixAssert.CompareLineByLine(new[] + { "The CommandLine/@Condition attribute's value '=' is not a valid bundle condition.", "The MsiPackage/@InstallCondition attribute's value '=' is not a valid bundle condition.", "The MsiProperty/@Condition attribute's value '=' is not a valid bundle condition.", "The 'REINSTALLMODE' MsiProperty is controlled by the bootstrapper and cannot be authored. (Illegal properties are: 'ACTION', 'ADDLOCAL', 'ADDSOURCE', 'ADDDEFAULT', 'ADVERTISE', 'ALLUSERS', 'REBOOT', 'REINSTALL', 'REINSTALLMODE', or 'REMOVE'.) Remove the MsiProperty element.", - }, messages.ToArray()); + }, errorMessages.ToArray()); - Assert.Equal(1159, result.ExitCode); + Assert.Equal(409, result.ExitCode); } } } diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithInvalidLocValues.wxl b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithInvalidLocValues.wxl index 0b5fac56..da2de367 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithInvalidLocValues.wxl +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithInvalidLocValues.wxl @@ -1,6 +1,8 @@ REINSTALLMODE WixBundleInstalled + WixBundleLog + WixCustomVariable WixBundleAction = 4 = WixBundleInstalled <> 1 diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithInvalidLocValues.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithInvalidLocValues.wxs index 74f66bbb..6e1a4dd7 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithInvalidLocValues.wxs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithInvalidLocValues.wxs @@ -13,5 +13,7 @@ + + diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithReservedVariableNames.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithReservedVariableNames.wxs index 3a38e2c9..af0e6625 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithReservedVariableNames.wxs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithReservedVariableNames.wxs @@ -1,7 +1,6 @@ - -- cgit v1.2.3-55-g6feb