From 84e7b6d277e5c3d118e11a45834d420254a758c0 Mon Sep 17 00:00:00 2001
From: Rob Mensching <rob@firegiant.com>
Date: Wed, 10 Aug 2022 13:28:34 -0700
Subject: Prevent crash when Bundle has SWID Tag but child MSI does not

Fixes 6854
---
 .../WixAdditionalTools/WixAdditionalTools.wxs      |  3 +-
 .../Bind/ProcessBundleSoftwareTagsCommand.cs       |  9 ++--
 .../SoftwareTagFixture.cs                          | 51 +++++++++++++++++++++-
 3 files changed, 57 insertions(+), 6 deletions(-)

diff --git a/src/setup/WixAdditionalTools/WixAdditionalTools.wxs b/src/setup/WixAdditionalTools/WixAdditionalTools.wxs
index a53db9d3..c54f6100 100644
--- a/src/setup/WixAdditionalTools/WixAdditionalTools.wxs
+++ b/src/setup/WixAdditionalTools/WixAdditionalTools.wxs
@@ -13,8 +13,7 @@
     </BootstrapperApplication>
 
     <SetVariable Variable="InstallFolder" Value="[ProgramFilesFolder]WiX Toolset v$(SetupMajorMinorVersion)\" />
-    <!-- TODO: bring back SoftwareTag when #6854 fixed -->
-    <!-- <SoftwareTag Regid="!(loc.Regid)" InstallPath="[InstallFolder]" /> -->
+    <SoftwareTag Regid="!(loc.Regid)" InstallPath="[InstallFolder]" />
 
     <Update Location="!(loc.UpdateUrl)" />
 
diff --git a/src/wix/WixToolset.Core.Burn/Bind/ProcessBundleSoftwareTagsCommand.cs b/src/wix/WixToolset.Core.Burn/Bind/ProcessBundleSoftwareTagsCommand.cs
index f9ff23cb..1962660f 100644
--- a/src/wix/WixToolset.Core.Burn/Bind/ProcessBundleSoftwareTagsCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bind/ProcessBundleSoftwareTagsCommand.cs
@@ -71,11 +71,14 @@ namespace WixToolset.Core.Burn.Bind
 
                     using (var db = new Database(payload.SourceFile.Path, OpenDatabase.ReadOnly))
                     {
-                        using (var view = db.OpenExecuteView("SELECT `Regid`, `TagId` FROM `SoftwareIdentificationTag`"))
+                        if (db.TableExists("SoftwareIdentificationTag"))
                         {
-                            foreach (var record in view.Records)
+                            using (var view = db.OpenExecuteView("SELECT `Regid`, `TagId` FROM `SoftwareIdentificationTag`"))
                             {
-                                tags.Add(new SoftwareTag { Regid = record.GetString(1), Id = record.GetString(2) });
+                                foreach (var record in view.Records)
+                                {
+                                    tags.Add(new SoftwareTag { Regid = record.GetString(1), Id = record.GetString(2) });
+                                }
                             }
                         }
                     }
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/SoftwareTagFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/SoftwareTagFixture.cs
index 9ff97e8c..544fcbda 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/SoftwareTagFixture.cs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/SoftwareTagFixture.cs
@@ -13,7 +13,7 @@ namespace WixToolsetTest.CoreIntegration
     public class SoftwareTagFixture
     {
         private static readonly XNamespace BurnManifestNamespace = "http://wixtoolset.org/schemas/v4/2008/Burn";
-        private static readonly XNamespace SwidTagNamespace = "http://standards.iso.org/iso/19770/-2/2009/schema.xsd";
+        private static readonly XNamespace SwidTagNamespace = "http://standards.iso.org/iso/19770/-2/2015/schema.xsd";
 
         [Fact]
         public void CanBuildPackageWithTag()
@@ -87,6 +87,55 @@ namespace WixToolsetTest.CoreIntegration
                     var version = docTag.Root.Attribute("version").Value;
                     Assert.Equal("~TagTestBundle", title);
                     Assert.Equal("4.3.2.1", version);
+
+                    var msiLink = docTag.Root.Elements(SwidTagNamespace + "Link").Single();
+                    Assert.Equal("component", msiLink.Attribute("rel").Value);
+                    Assert.StartsWith("swid:msi:package/", msiLink.Attribute("href").Value);
+                }
+            }
+        }
+
+        [Fact]
+        public void CanBuildBundleWithTagWhereMsiDoesNotHaveTag()
+        {
+            var testDataFolder = TestData.Get(@"TestData");
+
+            using (var fs = new DisposableFileSystem())
+            {
+                var baseFolder = fs.GetFolder();
+                var intermediateFolder = Path.Combine(baseFolder, "obj");
+
+                var result = WixRunner.Execute(new[]
+                {
+                    "build",
+                    Path.Combine(testDataFolder, "BundleTag", "BundleWithTag.wxs"),
+                    "-bindpath", Path.Combine(testDataFolder, "SimpleBundle", "data"),
+                    "-intermediateFolder", intermediateFolder,
+                    "-o", Path.Combine(baseFolder, @"bin\test.exe")
+                });
+
+                result.AssertSuccess();
+
+                Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.exe")));
+                Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.wixpdb")));
+
+                using (var ouput = WixOutput.Read(Path.Combine(baseFolder, @"bin\test.wixpdb")))
+                {
+                    var badata = ouput.GetDataStream("wix-burndata.xml");
+                    var doc = XDocument.Load(badata);
+
+                    var swidTag = doc.Root.Element(BurnManifestNamespace + "Registration").Element(BurnManifestNamespace + "SoftwareTag").Value;
+
+                    var swidTagPath = Path.Combine(baseFolder, "test.swidtag");
+                    File.WriteAllText(swidTagPath, swidTag);
+
+                    var docTag = XDocument.Load(swidTagPath);
+                    var title = docTag.Root.Attribute("name").Value;
+                    var version = docTag.Root.Attribute("version").Value;
+                    Assert.Equal("~TagTestBundle", title);
+                    Assert.Equal("4.3.2.1", version);
+
+                    Assert.Empty(docTag.Root.Elements(SwidTagNamespace + "Link"));
                 }
             }
         }
-- 
cgit v1.2.3-55-g6feb