@joebigelow / wix / commits / 8b959ca4

Handle case when invalid icon or splash screen are added to bundle

Fixes 5330

Rob Mensching committed Mar 11, 2022 at 16:43 UTC 8b959ca40baf44454d03fd14ef98482c52417681
6 files changed +94 -17
src/api/wix/WixToolset.Data/Symbols/WixBundleSymbol.cs
+4 -4
@@ -183,15 +183,15 @@ namespace WixToolset.Data.Symbols
183 set => this.Set((int)WixBundleSymbolFields.LogExtension, value);
184 }
185
186 - public string IconSourceFile
186 + public IntermediateFieldPathValue IconSourceFile
187 {
188 - get => (string)this.Fields[(int)WixBundleSymbolFields.IconSourceFile];
188 + get => this.Fields[(int)WixBundleSymbolFields.IconSourceFile].AsPath();
189 set => this.Set((int)WixBundleSymbolFields.IconSourceFile, value);
190 }
191
192 - public string SplashScreenSourceFile
192 + public IntermediateFieldPathValue SplashScreenSourceFile
193 {
194 - get => (string)this.Fields[(int)WixBundleSymbolFields.SplashScreenSourceFile];
194 + get => this.Fields[(int)WixBundleSymbolFields.SplashScreenSourceFile].AsPath();
195 set => this.Set((int)WixBundleSymbolFields.SplashScreenSourceFile, value);
196 }
197
src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs
+24 -11
@@ -259,11 +259,11 @@ namespace WixToolset.Core.Burn.Bundles
259 return new Version(major, minor, build, revision);
260 }
261
262 - private static void UpdateBurnResources(string bundleTempPath, string outputPath, WixBundleSymbol bundleInfo, Version windowsAssemblyVersion, byte[] applicationManifestData)
262 + private void UpdateBurnResources(string bundleTempPath, string outputPath, WixBundleSymbol bundleInfo, Version windowsAssemblyVersion, byte[] applicationManifestData)
263 {
264 const int burnLocale = 1033;
265 - var resources = new Dtf.Resources.ResourceCollection();
266 - var version = new Dtf.Resources.VersionResource("#1", burnLocale);
265 + var resources = new ResourceCollection();
266 + var version = new VersionResource("#1", burnLocale);
267
268 version.Load(bundleTempPath);
269 resources.Add(version);
@@ -292,10 +292,10 @@ namespace WixToolset.Core.Burn.Bundles
292 strings["CompanyName"] = String.Empty;
293 }
294
295 - if (!String.IsNullOrEmpty(bundleInfo.IconSourceFile))
295 + if (bundleInfo.IconSourceFile != null)
296 {
297 - var iconGroup = new Dtf.Resources.GroupIconResource("#1", burnLocale);
298 - iconGroup.ReadFromFile(bundleInfo.IconSourceFile);
297 + var iconGroup = new GroupIconResource("#1", burnLocale);
298 + iconGroup.ReadFromFile(bundleInfo.IconSourceFile.Path);
299 resources.Add(iconGroup);
300
301 foreach (var icon in iconGroup.Icons)
@@ -306,10 +306,10 @@ namespace WixToolset.Core.Burn.Bundles
306
307 var splashScreenType = BURN_SPLASH_SCREEN_TYPE.BURN_SPLASH_SCREEN_TYPE_NONE;
308
309 - if (!String.IsNullOrEmpty(bundleInfo.SplashScreenSourceFile))
309 + if (bundleInfo.SplashScreenSourceFile != null)
310 {
311 - var bitmap = new Dtf.Resources.BitmapResource("#1", burnLocale);
312 - bitmap.ReadFromFile(bundleInfo.SplashScreenSourceFile);
311 + var bitmap = new BitmapResource("#1", burnLocale);
312 + bitmap.ReadFromFile(bundleInfo.SplashScreenSourceFile.Path);
313 resources.Add(bitmap);
314
315 splashScreenType = BURN_SPLASH_SCREEN_TYPE.BURN_SPLASH_SCREEN_TYPE_BITMAP_RESOURCE;
@@ -321,13 +321,26 @@ namespace WixToolset.Core.Burn.Bundles
321 ResourceId = 1,
322 };
323
324 - var splashScreenConfigResource = new Dtf.Resources.Resource(ResourceType.RCData, "#1", burnLocale, splashScreenConfig.ToBytes());
324 + var splashScreenConfigResource = new Resource(ResourceType.RCData, "#1", burnLocale, splashScreenConfig.ToBytes());
325 resources.Add(splashScreenConfigResource);
326
327 var manifestResource = new Resource(ResourceType.Manifest, "#1", burnLocale, applicationManifestData);
328 resources.Add(manifestResource);
329
330 - resources.Save(bundleTempPath);
330 + try
331 + {
332 + resources.Save(bundleTempPath);
333 + }
334 + catch (IOException)
335 + {
336 + // If there was no icon or splash screen then this is unexpected so rethrow.
337 + if (bundleInfo.IconSourceFile == null && bundleInfo.SplashScreenSourceFile == null)
338 + {
339 + throw;
340 + }
341 +
342 + this.Messaging.Write(BurnBackendErrors.FailedToAddIconOrSplashScreenToBundle(bundleInfo.SourceLineNumbers, bundleInfo.IconSourceFile?.Path, bundleInfo.SplashScreenSourceFile?.Path));
343 + }
344 }
345
346 enum BURN_SPLASH_SCREEN_TYPE
src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs
+25
@@ -2,6 +2,7 @@
2
3 namespace WixToolset.Core.Burn
4 {
5 + using System;
6 using WixToolset.Data;
7
8 internal static class BurnBackendErrors
@@ -36,6 +37,29 @@ namespace WixToolset.Core.Burn
37 return Message(sourceLineNumbers, Ids.ExternalPayloadCollision2, "The location of the symbol related to the previous error.");
38 }
39
40 + public static Message FailedToAddIconOrSplashScreenToBundle(SourceLineNumber sourceLineNumbers, string iconPath, string splashScreenPath)
41 + {
42 + var additionalDetail = String.Empty;
43 +
44 + if (String.IsNullOrEmpty(iconPath) && String.IsNullOrEmpty(splashScreenPath))
45 + {
46 + }
47 + else if (String.IsNullOrEmpty(iconPath))
48 + {
49 + additionalDetail = $" Ensure the splash screen file is a bitmap file at '{splashScreenPath}'";
50 + }
51 + else if (String.IsNullOrEmpty(splashScreenPath))
52 + {
53 + additionalDetail = $" Ensure the bundle icon file is an icon file at '{iconPath}'";
54 + }
55 + else
56 + {
57 + additionalDetail = $" Ensure the bundle icon file is an icon file at '{iconPath}' and the splash screen file is a bitmap file at '{splashScreenPath}'";
58 + }
59 +
60 + return Message(sourceLineNumbers, Ids.FailedToAddIconOrSplashScreenToBundle, "Failed to add resources to the bundle.{0}", additionalDetail);
61 + }
62 +
63 public static Message PackageCachePayloadCollision(SourceLineNumber sourceLineNumbers, string payloadId, string payloadName, string packageId)
64 {
65 return Message(sourceLineNumbers, Ids.PackageCachePayloadCollision, "The Payload '{0}' has a duplicate Name '{1}' in package '{2}'. When caching the package, the file will get overwritten.", payloadId, payloadName, packageId);
@@ -79,6 +103,7 @@ namespace WixToolset.Core.Burn
103 TooManyAttachedContainers = 8008,
104 IncompatibleWixBurnSection = 8009,
105 UnsupportedRemotePackagePayload = 8010,
106 + FailedToAddIconOrSplashScreenToBundle = 8011,
107 } // last available is 8499. 8500 is BurnBackendWarnings.
108 }
109 }
src/wix/WixToolset.Core/Compiler_Bundle.cs
+2 -2
@@ -425,8 +425,8 @@ namespace WixToolset.Core
425 UpdateUrl = updateUrl,
426 CommandLineVariables = commandLineVariables,
427 Compressed = YesNoDefaultType.Yes == compressed ? true : YesNoDefaultType.No == compressed ? (bool?)false : null,
428 - IconSourceFile = iconSourceFile,
429 - SplashScreenSourceFile = splashScreenSourceFile,
428 + IconSourceFile = new IntermediateFieldPathValue { Path = iconSourceFile },
429 + SplashScreenSourceFile = new IntermediateFieldPathValue { Path = splashScreenSourceFile },
430 Condition = condition,
431 Tag = tag,
432 Platform = this.CurrentPlatform,
src/wix/test/WixToolsetTest.CoreIntegration/BundleFixture.cs
+28
@@ -291,6 +291,34 @@ namespace WixToolsetTest.CoreIntegration
291 }
292 }
293
294 + [Fact]
295 + public void CannotBuildBundleWithInvalidIcon()
296 + {
297 + var folder = TestData.Get(@"TestData");
298 +
299 + using (var fs = new DisposableFileSystem())
300 + {
301 + var baseFolder = fs.GetFolder();
302 + var intermediateFolder = Path.Combine(baseFolder, "obj");
303 +
304 + var result = WixRunner.Execute(new[]
305 + {
306 + "build",
307 + Path.Combine(folder, "BundleWithInvalid", "BundleWithInvalidIcon.wxs"),
308 + "-bindpath", Path.Combine(folder, ".Data"),
309 + "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
310 + "-intermediateFolder", intermediateFolder,
311 + "-o", Path.Combine(baseFolder, @"bin\test.exe")
312 + });
313 +
314 + var message = result.Messages.Where(m => m.Level == MessageLevel.Error).Select(m => m.ToString().Replace(folder, "<testdata>")).ToArray();
315 + WixAssert.CompareLineByLine(new[]
316 + {
317 + @"Failed to add resources to the bundle. Ensure the bundle icon file is an icon file at '<testdata>\.Data\burn.exe'"
318 + }, message);
319 + }
320 + }
321 +
322 [Fact]
323 public void CanBuildUncompressedBundle()
324 {
src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithInvalidIcon.wxs new
+11
@@ -0,0 +1,11 @@
1 +<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
2 + <Bundle Name="BundleWithIcon" IconSourceFile="burn.exe"
3 + Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="B94478B1-E1F3-4700-9CE8-6AA090854AEC">
4 + <BootstrapperApplication>
5 + <BootstrapperApplicationDll SourceFile="fakeba.dll" />
6 + </BootstrapperApplication>
7 + <Chain>
8 + <ExePackage DetectCondition="DetectedSomething" UninstallArguments="-uninstall" SourceFile="burn.exe" />
9 + </Chain>
10 + </Bundle>
11 +</Wix>