@joebigelow / wix / commits / 0fcd544b

Expose and use methods to parse attributes with Burn variable names.

Fixes 6819

Sean Hall committed Jul 21, 2022 at 15:45 UTC 0fcd544b7d2fbdf37227df055122b17428d9a524
15 files changed +117 -48
src/api/wix/WixToolset.Data/ErrorMessages.cs
+5
@@ -1804,6 +1804,11 @@ namespace WixToolset.Data
1804 return Message(sourceLineNumbers, Ids.RelativePathForRegistryElement, "Cannot convert RelativePath into Registry elements.");
1805 }
1806
1807 + public static Message ReservedBurnNamespaceViolation(SourceLineNumber sourceLineNumbers, string element, string attribute, string prefix)
1808 + {
1809 + return Message(sourceLineNumbers, Ids.ReservedNamespaceViolation, "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);
1810 + }
1811 +
1812 public static Message ReservedNamespaceViolation(SourceLineNumber sourceLineNumbers, string element, string attribute, string prefix)
1813 {
1814 return Message(sourceLineNumbers, Ids.ReservedNamespaceViolation, "The {0}/@{1} attribute's value begins with the reserved prefix '{2}'. Some prefixes are reserved by the Windows Installer and WiX toolset for well-known values. Change your attribute's value to not begin with the same prefix.", element, attribute, prefix);
src/api/wix/WixToolset.Data/Symbols/WixBundleVariableSymbol.cs
+17
@@ -35,6 +35,7 @@ namespace WixToolset.Data.Symbols
35 None = 0x0,
36 Hidden = 0x1,
37 Persisted = 0x2,
38 + BuiltIn = 0x4,
39 }
40
41 public enum WixBundleVariableType
@@ -107,5 +108,21 @@ namespace WixToolset.Data.Symbols
108 }
109 }
110 }
111 +
112 + public bool BuiltIn
113 + {
114 + get { return this.Attributes.HasFlag(WixBundleVariableAttributes.BuiltIn); }
115 + set
116 + {
117 + if (value)
118 + {
119 + this.Attributes |= WixBundleVariableAttributes.BuiltIn;
120 + }
121 + else
122 + {
123 + this.Attributes &= ~WixBundleVariableAttributes.BuiltIn;
124 + }
125 + }
126 + }
127 }
128 }
src/api/wix/WixToolset.Extensibility/Services/IBundleValidator.cs
+2 -1
@@ -39,8 +39,9 @@ namespace WixToolset.Extensibility.Services
39 /// <param name="elementName"></param>
40 /// <param name="attributeName"></param>
41 /// <param name="variableName"></param>
42 + /// <param name="allowBuiltIn">Whether to bypass checks for reserved values.</param>
43 /// <returns>Whether the name is valid.</returns>
43 - bool ValidateBundleVariableName(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName);
44 + bool ValidateBundleVariableName(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName, bool allowBuiltIn);
45
46 /// <summary>
47 /// Validates a bundle condition and displays an error for an illegal value.
src/api/wix/WixToolset.Extensibility/Services/IParseHelper.cs
+16
@@ -233,6 +233,22 @@ namespace WixToolset.Extensibility.Services
233 /// <returns>The attribute's value.</returns>
234 string GetAttributeValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, EmptyRule emptyRule = EmptyRule.CanBeWhitespaceOnly);
235
236 + /// <summary>
237 + /// Gets a bundle variable name identifier and displays an error for an illegal value.
238 + /// </summary>
239 + /// <param name="sourceLineNumbers">Source line information about the owner element.</param>
240 + /// <param name="attribute">The attribute containing the value to get.</param>
241 + /// <returns>The attribute's identifier value or a special value if an error occurred.</returns>
242 + Identifier GetAttributeBundleVariableNameIdentifier(SourceLineNumber sourceLineNumbers, XAttribute attribute);
243 +
244 + /// <summary>
245 + /// Gets a bundle variable name value and displays an error for an illegal value.
246 + /// </summary>
247 + /// <param name="sourceLineNumbers">Source line information about the owner element.</param>
248 + /// <param name="attribute">The attribute containing the value to get.</param>
249 + /// <returns>The attribute's value.</returns>
250 + string GetAttributeBundleVariableNameValue(SourceLineNumber sourceLineNumbers, XAttribute attribute);
251 +
252 /// <summary>
253 /// Get a guid attribute value and displays an error for an illegal guid value.
254 /// </summary>
src/ext/Util/test/WixToolsetTest.Util/TestData/BundleWithSearches/BundleUsingBuiltinVariableNames.wxs
+8
@@ -37,6 +37,14 @@
37 Value="Release"
38 Result="value"
39 Bitness="always64" />
40 +
41 + <util:RegistrySearch
42 + Variable="WixCustomVariable"
43 + Root="HKLM"
44 + Key="SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Custom"
45 + Value="Release"
46 + Result="value"
47 + Bitness="always64" />
48 </Fragment>
49
50 <Fragment>
src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs
+1
@@ -328,6 +328,7 @@ namespace WixToolsetTest.Util
328 "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'.",
329 "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'.",
330 "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'.",
331 + "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.",
332 "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'.",
333 "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'.",
334 "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'.",
src/ext/Util/wixext/UtilCompiler.cs
+13 -14
@@ -415,8 +415,7 @@ namespace WixToolset.Util
415 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
416 break;
417 case "Variable":
418 - variable = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
419 - // TODO: handle standard bundle variables
418 + variable = this.ParseHelper.GetAttributeBundleVariableNameValue(sourceLineNumbers, attrib);
419 break;
420 case "Condition":
421 condition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
@@ -505,10 +504,10 @@ namespace WixToolset.Util
504
505 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
506
508 - this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, null);
509 -
507 if (!this.Messaging.EncounteredError)
508 {
509 + this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, null);
510 +
511 section.AddSymbol(new WixComponentSearchSymbol(sourceLineNumbers, id)
512 {
513 Guid = guid,
@@ -616,10 +615,10 @@ namespace WixToolset.Util
615 this.Messaging.Write(ErrorMessages.UnsupportedPlatformForElement(sourceLineNumbers, this.Context.Platform.ToString(), element.Name.LocalName));
616 }
617
619 - this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, bundleExtensionId);
620 -
618 if (!this.Messaging.EncounteredError)
619 {
620 + this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, bundleExtensionId);
621 +
622 section.AddSymbol(new WixWindowsFeatureSearchSymbol(sourceLineNumbers, id)
623 {
624 Type = feature,
@@ -1043,10 +1042,10 @@ namespace WixToolset.Util
1042
1043 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
1044
1046 - this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, null);
1047 -
1045 if (!this.Messaging.EncounteredError)
1046 {
1047 + this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, null);
1048 +
1049 this.CreateWixFileSearchRow(section, sourceLineNumbers, id, path, attributes, type);
1050 }
1051 }
@@ -1157,10 +1156,10 @@ namespace WixToolset.Util
1156
1157 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
1158
1160 - this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, node.Name.LocalName, id, variable, condition, after, null);
1161 -
1159 if (!this.Messaging.EncounteredError)
1160 {
1161 + this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, node.Name.LocalName, id, variable, condition, after, null);
1162 +
1163 this.CreateWixFileSearchRow(section, sourceLineNumbers, id, path, attributes, type);
1164 }
1165 }
@@ -2645,10 +2644,10 @@ namespace WixToolset.Util
2644
2645 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
2646
2648 - this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, null);
2649 -
2647 if (!this.Messaging.EncounteredError)
2648 {
2649 + this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, null);
2650 +
2651 section.AddSymbol(new WixProductSearchSymbol(sourceLineNumbers, id)
2652 {
2653 Guid = guid,
@@ -2777,10 +2776,10 @@ namespace WixToolset.Util
2776
2777 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
2778
2780 - this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, null);
2781 -
2779 if (!this.Messaging.EncounteredError)
2780 {
2781 + this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, null);
2782 +
2783 section.AddSymbol(new WixRegistrySearchSymbol(sourceLineNumbers, id)
2784 {
2785 Root = root.Value,
src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs
+2 -2
@@ -163,7 +163,7 @@ namespace WixToolset.Core.Burn.Bundles
163
164 private void ValidateSearch(WixSearchSymbol symbol)
165 {
166 - this.BackendHelper.ValidateBundleVariableName(symbol.SourceLineNumbers, "*Search", "Variable", symbol.Variable);
166 + this.BackendHelper.ValidateBundleVariableName(symbol.SourceLineNumbers, "*Search", "Variable", symbol.Variable, allowBuiltIn: false);
167
168 if (symbol.Condition != null)
169 {
@@ -173,7 +173,7 @@ namespace WixToolset.Core.Burn.Bundles
173
174 private void ValidateVariable(WixBundleVariableSymbol symbol)
175 {
176 - this.BackendHelper.ValidateBundleVariableName(symbol.SourceLineNumbers, "Variable", "Name", symbol.Id.Id);
176 + this.BackendHelper.ValidateBundleVariableName(symbol.SourceLineNumbers, "Variable", "Name", symbol.Id.Id, allowBuiltIn: symbol.BuiltIn);
177 }
178 }
179 }
src/wix/WixToolset.Core.Burn/ExtensibilityServices/BurnBackendHelper.cs
+2 -2
@@ -190,9 +190,9 @@ namespace WixToolset.Core.Burn.ExtensibilityServices
190 return this.bundleValidator.ValidateBundleMsiPropertyName(sourceLineNumbers, elementName, attributeName, propertyName);
191 }
192
193 - public bool ValidateBundleVariableName(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName)
193 + public bool ValidateBundleVariableName(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName, bool allowBuiltIn)
194 {
195 - return this.bundleValidator.ValidateBundleVariableName(sourceLineNumbers, elementName, attributeName, variableName);
195 + return this.bundleValidator.ValidateBundleVariableName(sourceLineNumbers, elementName, attributeName, variableName, allowBuiltIn);
196 }
197
198 public bool ValidateBundleCondition(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string condition, BundleConditionPhase phase)
src/wix/WixToolset.Core/CompilerCore.cs
+5 -12
@@ -744,19 +744,12 @@ namespace WixToolset.Core
744 /// <returns>The attribute's value.</returns>
745 public Identifier GetAttributeBundleVariableNameIdentifier(SourceLineNumber sourceLineNumbers, XAttribute attribute)
746 {
747 - var variableName = this.GetAttributeIdentifier(sourceLineNumbers, attribute);
748 -
749 - if (!String.IsNullOrEmpty(variableName?.Id))
750 - {
751 - this.bundleValidator.ValidateBundleVariableName(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, variableName.Id);
752 -
753 - if (variableName.Id.StartsWith("Wix", StringComparison.OrdinalIgnoreCase))
754 - {
755 - this.messaging.Write(ErrorMessages.ReservedNamespaceViolation(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, "Wix"));
756 - }
757 - }
747 + return this.parseHelper.GetAttributeBundleVariableNameIdentifier(sourceLineNumbers, attribute);
748 + }
749
759 - return variableName;
750 + public string GetAttributeBundleVariableNameValue(SourceLineNumber sourceLineNumbers, XAttribute attribute)
751 + {
752 + return this.parseHelper.GetAttributeBundleVariableNameValue(sourceLineNumbers, attribute);
753 }
754
755 /// <summary>
src/wix/WixToolset.Core/Compiler_Bundle.cs
+10 -13
@@ -462,35 +462,32 @@ namespace WixToolset.Core
462 Type = ContainerType.Attached,
463 });
464
465 + var wellKnownVariableAttributes = WixBundleVariableAttributes.Persisted | WixBundleVariableAttributes.BuiltIn;
466 +
467 // Ensure that the bundle stores the well-known persisted values.
468 this.Core.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Section, BurnConstants.BURN_BUNDLE_INPROGRESS_NAME))
469 {
468 - Hidden = false,
469 - Persisted = true,
470 + Attributes = wellKnownVariableAttributes,
471 });
472
473 this.Core.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Section, BurnConstants.BURN_BUNDLE_NAME))
474 {
474 - Hidden = false,
475 - Persisted = true,
475 + Attributes = wellKnownVariableAttributes,
476 });
477
478 this.Core.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Section, BurnConstants.BURN_BUNDLE_ORIGINAL_SOURCE))
479 {
480 - Hidden = false,
481 - Persisted = true,
480 + Attributes = wellKnownVariableAttributes,
481 });
482
483 this.Core.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Section, BurnConstants.BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER))
484 {
486 - Hidden = false,
487 - Persisted = true,
485 + Attributes = wellKnownVariableAttributes,
486 });
487
488 this.Core.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Section, BurnConstants.BURN_BUNDLE_LAST_USED_SOURCE))
489 {
492 - Hidden = false,
493 - Persisted = true,
490 + Attributes = wellKnownVariableAttributes,
491 });
492 }
493 }
@@ -3620,7 +3617,7 @@ namespace WixToolset.Core
3617 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
3618 break;
3619 case "Variable":
3623 - variable = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
3620 + variable = this.Core.GetAttributeBundleVariableNameValue(sourceLineNumbers, attrib);
3621 break;
3622 case "Condition":
3623 condition = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
@@ -3655,10 +3652,10 @@ namespace WixToolset.Core
3652 id = this.Core.CreateIdentifier("sbv", variable, condition, after, value, type.ToString());
3653 }
3654
3658 - this.Core.CreateWixSearchSymbol(sourceLineNumbers, node.Name.LocalName, id, variable, condition, after);
3659 -
3655 if (!this.Messaging.EncounteredError)
3656 {
3657 + this.Core.CreateWixSearchSymbol(sourceLineNumbers, node.Name.LocalName, id, variable, condition, after);
3658 +
3659 this.Core.AddSymbol(new WixSetVariableSymbol(sourceLineNumbers, id)
3660 {
3661 Value = value,
src/wix/WixToolset.Core/ExtensibilityServices/BundleValidator.cs
+8 -2
@@ -145,7 +145,7 @@ namespace WixToolset.Core.ExtensibilityServices
145 return relativePath;
146 }
147
148 - public bool ValidateBundleVariableName(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName)
148 + public bool ValidateBundleVariableName(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string variableName, bool allowBuiltIn)
149 {
150 if (String.IsNullOrEmpty(variableName))
151 {
@@ -159,13 +159,19 @@ namespace WixToolset.Core.ExtensibilityServices
159
160 return false;
161 }
162 - else if (BuiltinBundleVariables.Contains(variableName))
162 + else if (!allowBuiltIn && BuiltinBundleVariables.Contains(variableName))
163 {
164 var illegalValues = CreateValueList(ValueListKind.Or, BuiltinBundleVariables);
165 this.Messaging.Write(ErrorMessages.IllegalAttributeValueWithIllegalList(sourceLineNumbers, elementName, attributeName, variableName, illegalValues));
166
167 return false;
168 }
169 + else if (!allowBuiltIn && variableName.StartsWith("Wix", StringComparison.OrdinalIgnoreCase))
170 + {
171 + this.Messaging.Write(ErrorMessages.ReservedBurnNamespaceViolation(sourceLineNumbers, elementName, attributeName, "Wix"));
172 +
173 + return false;
174 + }
175 else
176 {
177 return true;
src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
+25 -1
@@ -248,7 +248,7 @@ namespace WixToolset.Core.ExtensibilityServices
248 }
249 else
250 {
251 - this.BundleValidator.ValidateBundleVariableName(sourceLineNumbers, elementName, "Variable", variable);
251 + this.BundleValidator.ValidateBundleVariableName(sourceLineNumbers, elementName, "Variable", variable, allowBuiltIn: false);
252 }
253
254 section.AddSymbol(new WixSearchSymbol(sourceLineNumbers, id)
@@ -316,6 +316,30 @@ namespace WixToolset.Core.ExtensibilityServices
316 });
317 }
318
319 + public Identifier GetAttributeBundleVariableNameIdentifier(SourceLineNumber sourceLineNumbers, XAttribute attribute)
320 + {
321 + var variableId = this.GetAttributeIdentifier(sourceLineNumbers, attribute);
322 +
323 + if (!String.IsNullOrEmpty(variableId?.Id))
324 + {
325 + this.BundleValidator.ValidateBundleVariableName(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, variableId.Id, allowBuiltIn: false);
326 + }
327 +
328 + return variableId;
329 + }
330 +
331 + public string GetAttributeBundleVariableNameValue(SourceLineNumber sourceLineNumbers, XAttribute attribute)
332 + {
333 + var variableName = this.GetAttributeValue(sourceLineNumbers, attribute);
334 +
335 + if (!String.IsNullOrEmpty(variableName))
336 + {
337 + this.BundleValidator.ValidateBundleVariableName(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, variableName, allowBuiltIn: false);
338 + }
339 +
340 + return variableName;
341 + }
342 +
343 public string GetAttributeGuidValue(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool generatable = false, bool canBeEmpty = false)
344 {
345 if (null == attribute)
src/wix/test/WixToolsetTest.CoreIntegration/BadInputFixture.cs
+2 -1
@@ -212,8 +212,9 @@ namespace WixToolsetTest.CoreIntegration
212
213 WixAssert.CompareLineByLine(new[]
214 {
215 + "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.",
216 "The SetVariable/@Variable attribute's value, 'WixBundleInstalled', 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'.",
216 - "The Variable/@Name attribute's value begins with the reserved prefix 'Wix'. Some prefixes are reserved by the Windows Installer and WiX toolset for well-known values. Change your attribute's value to not begin with the same prefix.",
217 + "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.",
218 "The Variable/@Name attribute's value, 'AppDataFolder', 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'.",
219 }, messages.ToArray());
220
src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithReservedVariableNames.wxs
+1
@@ -1,6 +1,7 @@
1 <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
2 <Fragment>
3 <SetVariable Id="Builtin" Variable="WixBundleInstalled" Value="1" />
4 + <SetVariable Id="Builtin" Variable="WixDoesNotExist" Value="2" />
5 <Variable Name="WixCustomVariable" />
6 <Variable Name="AppDataFolder" />
7 </Fragment>