diff --git a/schemas/JSON/manifests/latest/manifest.installer.latest.json b/schemas/JSON/manifests/latest/manifest.installer.latest.json index 5442e77897..59a7b19e12 100644 --- a/schemas/JSON/manifests/latest/manifest.installer.latest.json +++ b/schemas/JSON/manifests/latest/manifest.installer.latest.json @@ -60,6 +60,7 @@ "appx", "exe", "zip", + "tar", "inno", "nullsoft", "wix", diff --git a/src/AppInstallerCLICore/Resources.h b/src/AppInstallerCLICore/Resources.h index b35f9b3dc9..4bb2ae0648 100644 --- a/src/AppInstallerCLICore/Resources.h +++ b/src/AppInstallerCLICore/Resources.h @@ -32,6 +32,7 @@ namespace AppInstaller::CLI::Resource WINGET_DEFINE_RESOURCE_STRINGID(ArchitectureArgumentDescription); WINGET_DEFINE_RESOURCE_STRINGID(ArchiveFailedMalwareScan); WINGET_DEFINE_RESOURCE_STRINGID(ArchiveFailedMalwareScanOverridden); + WINGET_DEFINE_RESOURCE_STRINGID(ArchiveScanNotSupportedForTar); WINGET_DEFINE_RESOURCE_STRINGID(ArgumentForSinglePackageProvidedWithMultipleQueries); WINGET_DEFINE_RESOURCE_STRINGID(AuthenticationAccountArgumentDescription); WINGET_DEFINE_RESOURCE_STRINGID(AuthenticationModeArgumentDescription); diff --git a/src/AppInstallerCLICore/Workflows/ArchiveFlow.cpp b/src/AppInstallerCLICore/Workflows/ArchiveFlow.cpp index 912b394ee2..16a5cf8121 100644 --- a/src/AppInstallerCLICore/Workflows/ArchiveFlow.cpp +++ b/src/AppInstallerCLICore/Workflows/ArchiveFlow.cpp @@ -21,6 +21,13 @@ namespace AppInstaller::CLI::Workflow { if (context.Args.Contains(Execution::Args::Type::Manifest)) { + if (context.Get().value().BaseInstallerType == InstallerTypeEnum::Tar) + { + AICLI_LOG(CLI, Warning, << "Archive malware scan is not supported for tar archives"); + context.Reporter.Warn() << Resource::String::ArchiveScanNotSupportedForTar << std::endl; + return; + } + bool scanResult = Archive::ScanZipFile(context.Get()); if (scanResult) @@ -54,7 +61,10 @@ namespace AppInstaller::CLI::Workflow AICLI_LOG(CLI, Info, << "Extracting archive to: " << destinationFolder); context.Reporter.Info() << Resource::String::ExtractingArchive << std::endl; - if (Settings::User().Get() == Archive::ExtractionMethod::Tar) + const bool useTar = context.Get().value().BaseInstallerType == InstallerTypeEnum::Tar + || Settings::User().Get() == Archive::ExtractionMethod::Tar; + + if (useTar) { context << ShellExecuteExtractArchive(installerPath, destinationFolder); } diff --git a/src/AppInstallerCLICore/Workflows/DownloadFlow.cpp b/src/AppInstallerCLICore/Workflows/DownloadFlow.cpp index cd24892c44..629ac493f8 100644 --- a/src/AppInstallerCLICore/Workflows/DownloadFlow.cpp +++ b/src/AppInstallerCLICore/Workflows/DownloadFlow.cpp @@ -63,6 +63,18 @@ namespace AppInstaller::CLI::Workflow return L".msix"sv; case InstallerTypeEnum::Zip: return L".zip"sv; + case InstallerTypeEnum::Tar: + { + const auto& fileName = GetFileNameFromURI(installer->Url); + if (fileName.has_extension()) + { + return fileName.extension().c_str(); + } + else + { + return L".tar.gz"sv; + } + } case InstallerTypeEnum::Font: { const auto& fileName = GetFileNameFromURI(installer->Url); @@ -302,6 +314,7 @@ namespace AppInstaller::CLI::Workflow case InstallerTypeEnum::Wix: case InstallerTypeEnum::Font: case InstallerTypeEnum::Zip: + case InstallerTypeEnum::Tar: context << DownloadInstallerFile; break; case InstallerTypeEnum::Msix: diff --git a/src/AppInstallerCLICore/Workflows/InstallFlow.cpp b/src/AppInstallerCLICore/Workflows/InstallFlow.cpp index e52234a139..22995c71d8 100644 --- a/src/AppInstallerCLICore/Workflows/InstallFlow.cpp +++ b/src/AppInstallerCLICore/Workflows/InstallFlow.cpp @@ -460,6 +460,7 @@ namespace AppInstaller::CLI::Workflow context << details::PortableInstall; break; case InstallerTypeEnum::Zip: + case InstallerTypeEnum::Tar: context << details::ArchiveInstall; break; case InstallerTypeEnum::Font: diff --git a/src/AppInstallerCLICore/Workflows/RepairFlow.cpp b/src/AppInstallerCLICore/Workflows/RepairFlow.cpp index 404c0e3c79..76a241aaff 100644 --- a/src/AppInstallerCLICore/Workflows/RepairFlow.cpp +++ b/src/AppInstallerCLICore/Workflows/RepairFlow.cpp @@ -174,7 +174,7 @@ namespace AppInstaller::CLI::Workflow ShowPromptsForSinglePackage(/* ensureAcceptance */ true) << DownloadInstaller; - if (installerType == InstallerTypeEnum::Zip) + if (installerType == InstallerTypeEnum::Zip || installerType == InstallerTypeEnum::Tar) { context << ScanArchiveFromLocalManifest << diff --git a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw index b562e3022a..585bf37b21 100644 --- a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw +++ b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw @@ -1586,6 +1586,9 @@ Please specify one of them using the --source option to proceed. Extracting archive... + + Malware scanning is not supported for tar archives; proceeding without scan + Archive scan detected malware. To override this check use --ignore-local-archive-malware-scan {Locked="--ignore-local-archive-malware-scan"} diff --git a/src/AppInstallerCommonCore/Manifest/ManifestCommon.cpp b/src/AppInstallerCommonCore/Manifest/ManifestCommon.cpp index 18fb24e5fa..cb9188d0a7 100644 --- a/src/AppInstallerCommonCore/Manifest/ManifestCommon.cpp +++ b/src/AppInstallerCommonCore/Manifest/ManifestCommon.cpp @@ -142,6 +142,10 @@ namespace AppInstaller::Manifest { result = InstallerTypeEnum::Zip; } + else if (IsTarInstallerTypeAlias(inStrLower)) + { + result = InstallerTypeEnum::Tar; + } else if (inStrLower == "appx" || inStrLower == "msix") { result = InstallerTypeEnum::Msix; @@ -581,6 +585,8 @@ namespace AppInstaller::Manifest return "wix"sv; case InstallerTypeEnum::Zip: return "zip"sv; + case InstallerTypeEnum::Tar: + return "tar"sv; case InstallerTypeEnum::Burn: return "burn"sv; case InstallerTypeEnum::MSStore: @@ -973,7 +979,7 @@ namespace AppInstaller::Manifest bool IsArchiveType(InstallerTypeEnum installerType) { - return (installerType == InstallerTypeEnum::Zip); + return (installerType == InstallerTypeEnum::Zip || installerType == InstallerTypeEnum::Tar); } bool IsPortableType(InstallerTypeEnum installerType) diff --git a/src/AppInstallerCommonCore/Public/winget/ManifestCommon.h b/src/AppInstallerCommonCore/Public/winget/ManifestCommon.h index f97a21f34c..61b566ecf5 100644 --- a/src/AppInstallerCommonCore/Public/winget/ManifestCommon.h +++ b/src/AppInstallerCommonCore/Public/winget/ManifestCommon.h @@ -3,6 +3,7 @@ #pragma once #include #include +#include #include #include #include @@ -109,6 +110,7 @@ namespace AppInstaller::Manifest Msi, Nullsoft, Zip, + Tar, Msix, Exe, Burn, @@ -117,6 +119,16 @@ namespace AppInstaller::Manifest Font, }; + inline bool IsTarInstallerTypeAlias(std::string_view s) + { + using namespace std::string_view_literals; + static constexpr std::string_view aliases[] = { + "tar"sv, "tgz"sv, "tbz2"sv, "tbz"sv, "txz"sv, "tzst"sv, + "tar.gz"sv, "tar.bz2"sv, "tar.xz"sv, "tar.zst"sv, "tar.lz4"sv, + }; + return std::find(std::begin(aliases), std::end(aliases), s) != std::end(aliases); + } + enum class UpdateBehaviorEnum { Unknown, diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/ManifestDeserializer_1_0.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/ManifestDeserializer_1_0.cpp index 081f2f50e0..eae4fbf909 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/ManifestDeserializer_1_0.cpp +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/ManifestDeserializer_1_0.cpp @@ -519,6 +519,10 @@ namespace AppInstaller::Repository::Rest::Schema::V1_0::Json { return InstallerTypeEnum::Zip; } + else if (IsTarInstallerTypeAlias(inStrLower)) + { + return InstallerTypeEnum::Tar; + } else if (inStrLower == "appx" || inStrLower == "msix") { return InstallerTypeEnum::Msix; diff --git a/src/Microsoft.Management.Deployment/Converters.cpp b/src/Microsoft.Management.Deployment/Converters.cpp index 6594a6c054..b2254d6f96 100644 --- a/src/Microsoft.Management.Deployment/Converters.cpp +++ b/src/Microsoft.Management.Deployment/Converters.cpp @@ -285,6 +285,8 @@ namespace winrt::Microsoft::Management::Deployment::implementation return Microsoft::Management::Deployment::PackageInstallerType::Wix; case ::AppInstaller::Manifest::InstallerTypeEnum::Zip: return Microsoft::Management::Deployment::PackageInstallerType::Zip; + case ::AppInstaller::Manifest::InstallerTypeEnum::Tar: + return Microsoft::Management::Deployment::PackageInstallerType::Tar; case ::AppInstaller::Manifest::InstallerTypeEnum::Unknown: return Microsoft::Management::Deployment::PackageInstallerType::Unknown; } @@ -316,6 +318,8 @@ namespace winrt::Microsoft::Management::Deployment::implementation return ::AppInstaller::Manifest::InstallerTypeEnum::Wix; case Microsoft::Management::Deployment::PackageInstallerType::Zip: return ::AppInstaller::Manifest::InstallerTypeEnum::Zip; + case Microsoft::Management::Deployment::PackageInstallerType::Tar: + return ::AppInstaller::Manifest::InstallerTypeEnum::Tar; case Microsoft::Management::Deployment::PackageInstallerType::Unknown: return ::AppInstaller::Manifest::InstallerTypeEnum::Unknown; } diff --git a/src/Microsoft.Management.Deployment/PackageManager.idl b/src/Microsoft.Management.Deployment/PackageManager.idl index 7dce535960..cf8d4ca268 100644 --- a/src/Microsoft.Management.Deployment/PackageManager.idl +++ b/src/Microsoft.Management.Deployment/PackageManager.idl @@ -478,6 +478,11 @@ namespace Microsoft.Management.Deployment /// Font type. Font, }, + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 14)] + { + /// Tar type (includes .tar.gz, .tgz, .tar.bz2, .tar.xz, and bare .tar). + Tar, + }, }; /// The package installer scope. diff --git a/src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/PSObjects/PSPackageInstallerType.cs b/src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/PSObjects/PSPackageInstallerType.cs index 553d2004c4..abad76bffb 100644 --- a/src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/PSObjects/PSPackageInstallerType.cs +++ b/src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/PSObjects/PSPackageInstallerType.cs @@ -41,6 +41,11 @@ public enum PSPackageInstallerType /// Zip, + /// + /// Tar (includes .tar.gz, .tgz, .tar.bz2, .tar.xz, and bare .tar). + /// + Tar, + /// /// Msix. ///