| 1 | // 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. |
| 2 | |
| 3 | namespace WixToolsetTest.CoreIntegration |
| 4 | { |
| 5 | using System; |
| 6 | using System.IO; |
| 7 | using System.Linq; |
| 8 | using WixInternal.TestSupport; |
| 9 | using WixInternal.Core.TestPackage; |
| 10 | using WixToolset.Data; |
| 11 | using Xunit; |
| 12 | |
| 13 | public class BadInputFixture |
| 14 | { |
| 15 | [Fact] |
| 16 | public void HandleInvalidIds() |
| 17 | { |
| 18 | var folder = TestData.Get(@"TestData\BadInput"); |
| 19 | |
| 20 | using (var fs = new DisposableFileSystem()) |
| 21 | { |
| 22 | var baseFolder = fs.GetFolder(); |
| 23 | var intermediateFolder = Path.Combine(baseFolder, "obj"); |
| 24 | var wixlibPath = Path.Combine(intermediateFolder, @"test.wixlib"); |
| 25 | |
| 26 | var result = WixRunner.Execute(new[] |
| 27 | { |
| 28 | "build", |
| 29 | Path.Combine(folder, "InvalidIds.wxs"), |
| 30 | "-intermediateFolder", intermediateFolder, |
| 31 | "-o", wixlibPath, |
| 32 | }); |
| 33 | |
| 34 | Assert.Equal(330, result.ExitCode); |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | [Fact] |
| 39 | public void CantBuildSingleExeBundleWithInvalidArgument() |
| 40 | { |
| 41 | var folder = TestData.Get(@"TestData"); |
| 42 | |
| 43 | using (var fs = new DisposableFileSystem()) |
| 44 | { |
| 45 | var baseFolder = fs.GetFolder(); |
| 46 | var intermediateFolder = Path.Combine(baseFolder, "obj"); |
| 47 | var exePath = Path.Combine(baseFolder, @"bin\test.exe"); |
| 48 | |
| 49 | var result = WixRunner.Execute(new[] |
| 50 | { |
| 51 | "build", |
| 52 | Path.Combine(folder, "SingleExeBundle", "SingleExePackageGroup.wxs"), |
| 53 | Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"), |
| 54 | "-bindpath", Path.Combine(folder, "SimpleBundle", "data"), |
| 55 | "-bindpath", Path.Combine(folder, ".Data"), |
| 56 | "-intermediateFolder", intermediateFolder, |
| 57 | "-o", exePath, |
| 58 | "-nonexistentswitch", "param", |
| 59 | }); |
| 60 | |
| 61 | Assert.NotEqual(0, result.ExitCode); |
| 62 | Assert.False(File.Exists(exePath)); |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | [Fact] |
| 67 | public void RegistryKeyWithoutAttributesDoesntCrash() |
| 68 | { |
| 69 | var folder = TestData.Get(@"TestData\BadInput"); |
| 70 | |
| 71 | using (var fs = new DisposableFileSystem()) |
| 72 | { |
| 73 | var baseFolder = fs.GetFolder(); |
| 74 | var intermediateFolder = Path.Combine(baseFolder, "obj"); |
| 75 | var wixlibPath = Path.Combine(intermediateFolder, @"test.wixlib"); |
| 76 | |
| 77 | var result = WixRunner.Execute(new[] |
| 78 | { |
| 79 | "build", |
| 80 | Path.Combine(folder, "RegistryKey.wxs"), |
| 81 | "-intermediateFolder", intermediateFolder, |
| 82 | "-o", wixlibPath, |
| 83 | }); |
| 84 | |
| 85 | Assert.InRange(result.ExitCode, 2, Int32.MaxValue); |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | [Fact] |
| 90 | public void BundleExePackageWithNetfxProtocolIsRejected() |
| 91 | { |
| 92 | var folder = TestData.Get(@"TestData\BadInput"); |
| 93 | |
| 94 | using (var fs = new DisposableFileSystem()) |
| 95 | { |
| 96 | var baseFolder = fs.GetFolder(); |
| 97 | var intermediateFolder = Path.Combine(baseFolder, "obj"); |
| 98 | var wixlibPath = Path.Combine(intermediateFolder, @"test.wixlib"); |
| 99 | |
| 100 | var result = WixRunner.Execute(new[] |
| 101 | { |
| 102 | "build", |
| 103 | Path.Combine(folder, "BundleExePackageWithNetfxProtocol.wxs"), |
| 104 | "-intermediateFolder", intermediateFolder, |
| 105 | "-o", wixlibPath, |
| 106 | }); |
| 107 | |
| 108 | Assert.Equal(193, result.ExitCode); |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | [Fact] |
| 113 | public void BundleVariableWithBadTypeIsRejected() |
| 114 | { |
| 115 | var folder = TestData.Get(@"TestData\BadInput"); |
| 116 | |
| 117 | using (var fs = new DisposableFileSystem()) |
| 118 | { |
| 119 | var baseFolder = fs.GetFolder(); |
| 120 | var intermediateFolder = Path.Combine(baseFolder, "obj"); |
| 121 | var wixlibPath = Path.Combine(intermediateFolder, @"test.wixlib"); |
| 122 | |
| 123 | var result = WixRunner.Execute(new[] |
| 124 | { |
| 125 | "build", |
| 126 | Path.Combine(folder, "BundleVariable.wxs"), |
| 127 | "-intermediateFolder", intermediateFolder, |
| 128 | "-o", wixlibPath, |
| 129 | }); |
| 130 | |
| 131 | Assert.Equal(21, result.ExitCode); |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | [Fact] |
| 136 | public void BundleVariableWithHiddenPersistedIsRejected() |
| 137 | { |
| 138 | var folder = TestData.Get(@"TestData\BadInput"); |
| 139 | |
| 140 | using (var fs = new DisposableFileSystem()) |
| 141 | { |
| 142 | var baseFolder = fs.GetFolder(); |
| 143 | var intermediateFolder = Path.Combine(baseFolder, "obj"); |
| 144 | var wixlibPath = Path.Combine(intermediateFolder, @"test.wixlib"); |
| 145 | |
| 146 | var result = WixRunner.Execute(new[] |
| 147 | { |
| 148 | "build", |
| 149 | Path.Combine(folder, "HiddenPersistedBundleVariable.wxs"), |
| 150 | "-intermediateFolder", intermediateFolder, |
| 151 | "-o", wixlibPath, |
| 152 | }); |
| 153 | |
| 154 | Assert.Equal(193, result.ExitCode); |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | [Fact] |
| 159 | public void CannotBuildBundleWithLocVariableNames() |
| 160 | { |
| 161 | var folder = TestData.Get(@"TestData"); |
| 162 | |
| 163 | using (var fs = new DisposableFileSystem()) |
| 164 | { |
| 165 | var baseFolder = fs.GetFolder(); |
| 166 | var intermediateFolder = Path.Combine(baseFolder, "obj"); |
| 167 | var wixlibPath = Path.Combine(intermediateFolder, @"test.wixlib"); |
| 168 | |
| 169 | var result = WixRunner.Execute(new[] |
| 170 | { |
| 171 | "build", |
| 172 | Path.Combine(folder, "BundleWithInvalid", "BundleWithInvalidLocVariableNames.wxs"), |
| 173 | "-loc", Path.Combine(folder, "BundleWithInvalid", "BundleWithInvalidLocValues.wxl"), |
| 174 | "-intermediateFolder", intermediateFolder, |
| 175 | "-o", wixlibPath, |
| 176 | }); |
| 177 | |
| 178 | var messages = result.Messages.Select(m => m.ToString()).ToList(); |
| 179 | messages.Sort(); |
| 180 | |
| 181 | WixAssert.CompareLineByLine(new[] |
| 182 | { |
| 183 | "The Variable/@Name attribute was not found; it is required.", |
| 184 | "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.", |
| 185 | }, messages.ToArray()); |
| 186 | |
| 187 | Assert.Equal(10, result.ExitCode); |
| 188 | } |
| 189 | } |
| 190 | |
| 191 | [Fact] |
| 192 | public void CannotBuildBundleWithReservedVariableNames() |
| 193 | { |
| 194 | var folder = TestData.Get(@"TestData"); |
| 195 | |
| 196 | using (var fs = new DisposableFileSystem()) |
| 197 | { |
| 198 | var baseFolder = fs.GetFolder(); |
| 199 | var intermediateFolder = Path.Combine(baseFolder, "obj"); |
| 200 | var wixlibPath = Path.Combine(intermediateFolder, @"test.wixlib"); |
| 201 | |
| 202 | var result = WixRunner.Execute(new[] |
| 203 | { |
| 204 | "build", |
| 205 | Path.Combine(folder, "BundleWithInvalid", "BundleWithReservedVariableNames.wxs"), |
| 206 | "-intermediateFolder", intermediateFolder, |
| 207 | "-o", wixlibPath, |
| 208 | }); |
| 209 | |
| 210 | var messages = result.Messages.Select(m => m.ToString()).ToList(); |
| 211 | messages.Sort(); |
| 212 | |
| 213 | WixAssert.CompareLineByLine(new[] |
| 214 | { |
| 215 | "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'.", |
| 216 | "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'.", |
| 217 | }, messages.ToArray()); |
| 218 | |
| 219 | Assert.Equal(348, result.ExitCode); |
| 220 | } |
| 221 | } |
| 222 | |
| 223 | [Fact] |
| 224 | public void CannotBuildWithUnknownOutputType() |
| 225 | { |
| 226 | var folder = TestData.Get(@"TestData"); |
| 227 | |
| 228 | using (var fs = new DisposableFileSystem()) |
| 229 | { |
| 230 | var baseFolder = fs.GetFolder(); |
| 231 | var intermediateFolder = Path.Combine(baseFolder, "obj"); |
| 232 | var outputPath = Path.Combine(intermediateFolder, @"test.pkg"); |
| 233 | |
| 234 | var result = WixRunner.Execute(new[] |
| 235 | { |
| 236 | "build", |
| 237 | Path.Combine(folder, "SimplePackage", "SimplePackage.wxs"), |
| 238 | "-intermediateFolder", intermediateFolder, |
| 239 | "-bindpath", Path.Combine(folder, ".Data"), |
| 240 | "-outputType", "invalid", |
| 241 | "-o", outputPath, |
| 242 | }); |
| 243 | |
| 244 | var messages = result.Messages.Select(m => m.ToString()).ToList(); |
| 245 | messages.Sort(); |
| 246 | |
| 247 | WixAssert.CompareLineByLine(new[] |
| 248 | { |
| 249 | @"Unable to find a backend to process output type: invalid for output file: <folder>\test.pkg. Specify a different output type or output file extension.", |
| 250 | }, messages.Select(s => s.Replace(intermediateFolder, "<folder>")).ToArray()); |
| 251 | |
| 252 | Assert.Equal(7014, result.ExitCode); |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | [Fact] |
| 257 | public void GuardsAgainstVariousBundleValuesFromLoc() |
| 258 | { |
| 259 | var folder = TestData.Get(@"TestData"); |
| 260 | |
| 261 | using (var fs = new DisposableFileSystem()) |
| 262 | { |
| 263 | var baseFolder = fs.GetFolder(); |
| 264 | var intermediateFolder = Path.Combine(baseFolder, "obj"); |
| 265 | |
| 266 | var result = WixRunner.Execute(false, new[] |
| 267 | { |
| 268 | "build", |
| 269 | Path.Combine(folder, "BundleWithInvalid", "BundleWithInvalidLocValues.wxs"), |
| 270 | "-loc", Path.Combine(folder, "BundleWithInvalid", "BundleWithInvalidLocValues.wxl"), |
| 271 | "-bindpath", Path.Combine(folder, ".Data"), |
| 272 | "-bindpath", Path.Combine(folder, "DecompileSingleFileCompressed"), |
| 273 | "-bindpath", Path.Combine(folder, "SimpleBundle", "data"), |
| 274 | "-intermediateFolder", intermediateFolder, |
| 275 | "-o", Path.Combine(baseFolder, @"bin\test.exe") |
| 276 | }); |
| 277 | |
| 278 | var warningMessages = result.Messages.Where(m => m.Level == MessageLevel.Warning).Select(m => m.ToString()).OrderBy(s => s, StringComparer.Ordinal).ToArray(); |
| 279 | |
| 280 | WixAssert.CompareLineByLine(new[] |
| 281 | { |
| 282 | "*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.", |
| 283 | "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.", |
| 284 | "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.", |
| 285 | "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.", |
| 286 | }, warningMessages); |
| 287 | |
| 288 | var errorMessages = result.Messages.Where(m => m.Level == MessageLevel.Error).Select(m => m.ToString()).OrderBy(s => s, StringComparer.Ordinal).ToArray(); |
| 289 | |
| 290 | WixAssert.CompareLineByLine(new[] |
| 291 | { |
| 292 | "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.", |
| 293 | "The CommandLine/@Condition attribute's value '=' is not a valid bundle condition.", |
| 294 | "The MsiPackage/@InstallCondition attribute's value '=' is not a valid bundle condition.", |
| 295 | "The MsiProperty/@Condition attribute's value '=' is not a valid bundle condition.", |
| 296 | }, errorMessages); |
| 297 | |
| 298 | Assert.Equal(409, result.ExitCode); |
| 299 | } |
| 300 | } |
| 301 | } |
| 302 | } |