From 3be680c50c155544d12f5d9ace41cb70be545118 Mon Sep 17 00:00:00 2001
From: yao-msft <50888816+yao-msft@users.noreply.github.com>
Date: Tue, 25 Jul 2023 13:58:04 -0700
Subject: [PATCH] Skip stub packages for msix installer validation (#3468)
---
.../AppInstallerCLITests.vcxproj | 6 ++++++
.../AppInstallerCLITests.vcxproj.filters | 6 ++++++
.../Installer-Good-WithStub.msixbundle | Bin 0 -> 9941 bytes
...est-Good-MsixBundleInstaller-WithStub.yaml | 13 +++++++++++++
src/AppInstallerCLITests/YamlManifest.cpp | 14 ++++++++++++++
src/AppInstallerCommonCore/MsixInfo.cpp | 18 +++++++++++++-----
.../Public/AppInstallerMsixInfo.h | 6 +++---
7 files changed, 55 insertions(+), 8 deletions(-)
create mode 100644 src/AppInstallerCLITests/TestData/Installer-Good-WithStub.msixbundle
create mode 100644 src/AppInstallerCLITests/TestData/Manifest-Good-MsixBundleInstaller-WithStub.yaml
diff --git a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj
index 337e04a701..82e6059dcc 100644
--- a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj
+++ b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj
@@ -817,6 +817,9 @@
true
+
+ true
+
true
@@ -832,6 +835,9 @@
true
+
+ true
+
true
diff --git a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters
index 10e263ad17..6618fcdd05 100644
--- a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters
+++ b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters
@@ -852,6 +852,9 @@
TestData
+
+ TestData
+
TestData
@@ -867,6 +870,9 @@
TestData
+
+ TestData
+
TestData
diff --git a/src/AppInstallerCLITests/TestData/Installer-Good-WithStub.msixbundle b/src/AppInstallerCLITests/TestData/Installer-Good-WithStub.msixbundle
new file mode 100644
index 0000000000000000000000000000000000000000..40b5a01e53c41c91fa0fb948e74dc8fb697371bf
GIT binary patch
literal 9941
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
literal 0
HcmV?d00001
diff --git a/src/AppInstallerCLITests/TestData/Manifest-Good-MsixBundleInstaller-WithStub.yaml b/src/AppInstallerCLITests/TestData/Manifest-Good-MsixBundleInstaller-WithStub.yaml
new file mode 100644
index 0000000000..d8615bd146
--- /dev/null
+++ b/src/AppInstallerCLITests/TestData/Manifest-Good-MsixBundleInstaller-WithStub.yaml
@@ -0,0 +1,13 @@
+PackageIdentifier: AppInstallerCliTest.GoodMsixBundleInstaller
+PackageVersion: 43690.48059.52428.56797
+PackageLocale: es-MX
+PackageName: es-MX package name
+Publisher: es-MX publisher
+PackageFamilyName: FakeInstallerForTesting_125rzkzqaqjwj
+MinimumOSVersion: 10.0.16299.0
+InstallerType: msix
+Installers:
+ - Architecture: x64
+ InstallerUrl: Installer-Good-WithStub.msixbundle
+ManifestType: merged
+ManifestVersion: 1.0.0
diff --git a/src/AppInstallerCLITests/YamlManifest.cpp b/src/AppInstallerCLITests/YamlManifest.cpp
index ab25c53c3b..79f20771c7 100644
--- a/src/AppInstallerCLITests/YamlManifest.cpp
+++ b/src/AppInstallerCLITests/YamlManifest.cpp
@@ -1150,6 +1150,20 @@ TEST_CASE("ReadManifestAndValidateMsixBundleInstallers_Success", "[ManifestValid
REQUIRE(0 == errors.size());
}
+TEST_CASE("ReadManifestAndValidateMsixBundleInstallers_WithStub_Success", "[ManifestValidation]")
+{
+ TestDataFile testFile("Manifest-Good-MsixBundleInstaller-WithStub.yaml");
+ Manifest manifest = YamlParser::CreateFromPath(testFile);
+
+ // Update the installer path for testing
+ REQUIRE(1 == manifest.Installers.size());
+ TestDataFile msixFile(manifest.Installers[0].Url.c_str());
+ manifest.Installers[0].Url = msixFile.GetPath().u8string();
+
+ auto errors = ValidateManifestInstallers(manifest);
+ REQUIRE(0 == errors.size());
+}
+
TEST_CASE("ReadManifestAndValidateMsixBundleInstallers_InconsistentFields", "[ManifestValidation]")
{
TestDataFile testFile("Manifest-Bad-InconsistentMsixBundleInstallerFields.yaml");
diff --git a/src/AppInstallerCommonCore/MsixInfo.cpp b/src/AppInstallerCommonCore/MsixInfo.cpp
index 802b7bcf3a..6256bb8eea 100644
--- a/src/AppInstallerCommonCore/MsixInfo.cpp
+++ b/src/AppInstallerCommonCore/MsixInfo.cpp
@@ -623,7 +623,7 @@ namespace AppInstaller::Msix
return Utility::ConvertToUTF8(GetPackageFullNameWide());
}
- std::vector> MsixInfo::GetAppPackages() const
+ std::vector> MsixInfo::GetAppPackages(bool includeStub) const
{
if (!m_isBundle)
{
@@ -648,11 +648,19 @@ namespace AppInstaller::Msix
APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE packageType;
THROW_IF_FAILED(packageInfo->GetPackageType(&packageType));
+ // Check flat bundle case.
UINT64 offset;
THROW_IF_FAILED(packageInfo->GetOffset(&offset));
- const bool isContained = offset != 0;
+ bool isContained = offset != 0;
- if (isContained && packageType == APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE::APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_APPLICATION)
+ // Check stub package case.
+ ComPtr packageInfo4;
+ THROW_IF_FAILED(packageInfo.As(&packageInfo4));
+ BOOL isStub = FALSE;
+ THROW_IF_FAILED(packageInfo4->GetIsStub(&isStub));
+
+ if (isContained && (includeStub || !isStub) &&
+ packageType == APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE::APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_APPLICATION)
{
wil::unique_cotaskmem_string fileName;
THROW_IF_FAILED(packageInfo->GetFileName(&fileName));
@@ -680,10 +688,10 @@ namespace AppInstaller::Msix
return packages;
}
- std::vector MsixInfo::GetAppPackageManifests() const
+ std::vector MsixInfo::GetAppPackageManifests(bool includeStub) const
{
std::vector manifests;
- auto packages = GetAppPackages();
+ auto packages = GetAppPackages(includeStub);
for (const auto& package : packages)
{
ComPtr manifestReader;
diff --git a/src/AppInstallerCommonCore/Public/AppInstallerMsixInfo.h b/src/AppInstallerCommonCore/Public/AppInstallerMsixInfo.h
index 5ea9dba4a9..8d52581b75 100644
--- a/src/AppInstallerCommonCore/Public/AppInstallerMsixInfo.h
+++ b/src/AppInstallerCommonCore/Public/AppInstallerMsixInfo.h
@@ -91,7 +91,7 @@ namespace AppInstaller::Msix
void WriteToFileHandle(std::string_view packageFile, HANDLE target, IProgressCallback& progress);
// Get application package manifests from msix and msixbundle.
- std::vector GetAppPackageManifests() const;
+ std::vector GetAppPackageManifests(bool includeStub = false) const;
private:
bool m_isBundle;
@@ -99,8 +99,8 @@ namespace AppInstaller::Msix
Microsoft::WRL::ComPtr m_bundleReader;
Microsoft::WRL::ComPtr m_packageReader;
- // Get application packages.
- std::vector> GetAppPackages() const;
+ // Get application packages. Ignore stub packages if any.
+ std::vector> GetAppPackages(bool includeStub = false) const;
};
struct GetCertContextResult