Skip to content

Commit

Permalink
Fix archive scanner and implement tests
Browse files Browse the repository at this point in the history
  • Loading branch information
pl4nty committed Oct 27, 2024
1 parent 104864f commit ed21c90
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 88 deletions.
3 changes: 3 additions & 0 deletions src/AppInstallerCLITests/AppInstallerCLITests.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,9 @@
<CopyFileToFolders Include="TestData\TestZip.zip">
<DeploymentContent>true</DeploymentContent>
</CopyFileToFolders>
<CopyFileToFolders Include="TestData\TestTarGz.tar.gz">
<DeploymentContent>true</DeploymentContent>
</CopyFileToFolders>
<None Include="Run-TestsInPackage.ps1" />
<CopyFileToFolders Include="TestData\Manifest-Bad-ArchInvalid.yaml">
<DeploymentContent>true</DeploymentContent>
Expand Down
3 changes: 3 additions & 0 deletions src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,9 @@
<CopyFileToFolders Include="TestData\TestZip.zip">
<Filter>TestData</Filter>
</CopyFileToFolders>
<CopyFileToFolders Include="TestData\TestTarGz.tar.gz">
<Filter>TestData</Filter>
</CopyFileToFolders>
<CopyFileToFolders Include="TestData\DownloadFlowTest_DownloadCommandProhibited.yaml">
<Filter>TestData</Filter>
</CopyFileToFolders>
Expand Down
99 changes: 23 additions & 76 deletions src/AppInstallerCLITests/Archive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@
// Licensed under the MIT License.
#include "pch.h"
#include "TestCommon.h"
#include "WorkflowCommon.h"
#include <winget/Archive.h>
#include <Workflows/ShellExecuteInstallerHandler.h>

using namespace AppInstaller::Archive;
using namespace AppInstaller::CLI::Workflow;
using namespace AppInstaller::Settings;
using namespace TestCommon;

constexpr std::string_view s_ZipFile = "TestZip.zip";
constexpr std::string_view s_7zFile = "Test7z.7z";
constexpr std::string_view s_RarFile = "TestRar.rar";
constexpr std::string_view s_TarGzFile = "TestTarGz.tar.gz";
constexpr std::string_view s_TarBz2File = "TestTarBz2.tar.bz2";
constexpr std::string_view s_Large7zFile = "TestLarge7z.7z";

TEST_CASE("Extract_ZipArchive", "[archive]")
{
Expand All @@ -37,67 +39,27 @@ TEST_CASE("Scan_ZipArchive", "[archive]")
REQUIRE(result);
}

TEST_CASE("Extract_7zArchive", "[archive]")
{
TestCommon::TempDirectory tempDirectory("TempDirectory");
TestDataFile test7z(s_7zFile);

const auto& test7zPath = test7z.GetPath();
const auto& tempDirectoryPath = tempDirectory.GetPath();

HRESULT hr = TryExtractArchive(test7zPath, tempDirectoryPath);

std::filesystem::path expectedPath = tempDirectoryPath / "test.txt";
REQUIRE(SUCCEEDED(hr));
REQUIRE(std::filesystem::exists(expectedPath));
}

TEST_CASE("Scan_7zArchive", "[archive]")
{
TestDataFile test7z(s_7zFile);

const auto& test7zPath = test7z.GetPath();
bool result = ScanZipFile(test7zPath);
REQUIRE(result);
}

TEST_CASE("Extract_RarArchive", "[archive]")
{
TestCommon::TempDirectory tempDirectory("TempDirectory");
TestDataFile testRar(s_RarFile);

const auto& testRarPath = testRar.GetPath();
const auto& tempDirectoryPath = tempDirectory.GetPath();

HRESULT hr = TryExtractArchive(testRarPath, tempDirectoryPath);

std::filesystem::path expectedPath = tempDirectoryPath / "test.txt";
REQUIRE(SUCCEEDED(hr));
REQUIRE(std::filesystem::exists(expectedPath));
}

TEST_CASE("Scan_RarArchive", "[archive]")
{
TestDataFile testRar(s_RarFile);

const auto& testRarPath = testRar.GetPath();
bool result = ScanZipFile(testRarPath);
REQUIRE(result);
}

TEST_CASE("Extract_TarGzArchive", "[archive]")
{
TestCommon::TempDirectory tempDirectory("TempDirectory");
TestDataFile testTarGz(s_TarGzFile);

TestCommon::TestUserSettings testSettings;
testSettings.Set<Setting::ArchiveExtractionMethod>(AppInstaller::Archive::ExtractionMethod::Tar);

const auto& testTarGzPath = testTarGz.GetPath();
const auto& tempDirectoryPath = tempDirectory.GetPath();

HRESULT hr = TryExtractArchive(testTarGzPath, tempDirectoryPath);
ShellExecuteExtractArchive(testTarGzPath, tempDirectoryPath);

std::ostringstream extractOutput;
TestContext context{ extractOutput, std::cin };
context << ShellExecuteExtractArchive(testTarGzPath, tempDirectoryPath);

std::filesystem::path expectedPath = tempDirectoryPath / "test.txt";
REQUIRE(SUCCEEDED(hr));
REQUIRE(SUCCEEDED(context.GetTerminationHR()));
REQUIRE(std::filesystem::exists(expectedPath));
INFO(extractOutput.str());
}

TEST_CASE("Scan_TarGzArchive", "[archive]")
Expand All @@ -109,27 +71,12 @@ TEST_CASE("Scan_TarGzArchive", "[archive]")
REQUIRE(result);
}

TEST_CASE("Extract_TarBz2Archive", "[archive]")
{
TestCommon::TempDirectory tempDirectory("TempDirectory");
TestDataFile testTarBz2(s_TarBz2File);

const auto& testTarBz2Path = testTarBz2.GetPath();
const auto& tempDirectoryPath = tempDirectory.GetPath();

HRESULT hr = TryExtractArchive(testTarBz2Path, tempDirectoryPath);

std::filesystem::path expectedPath = tempDirectoryPath / "test.txt";
REQUIRE(SUCCEEDED(hr));
REQUIRE(std::filesystem::exists(expectedPath));
}

TEST_CASE("Scan_TarBz2Archive", "[archive]")
{
TestDataFile testTarBz2(s_TarBz2File);

const auto& testTarBz2Path = testTarBz2.GetPath();
bool result = ScanZipFile(testTarBz2Path);
REQUIRE(result);
}
//TEST_CASE("Scan_Large7zArchive", "[archive]")
//{
// TestDataFile testLarge7z(s_Large7zFile);
//
// const auto& testTarGzPath = testLarge7z.GetPath();
// bool result = ScanZipFile(testTarGzPath);
// REQUIRE(result);
//}

Binary file added src/AppInstallerCLITests/TestData/TestTarGz.tar.gz
Binary file not shown.
48 changes: 48 additions & 0 deletions src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,21 @@
<SubSystem Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">Windows</SubSystem>
<SubSystem Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Windows</SubSystem>
</Link>
<Lib>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">amsi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
<Lib>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">amsi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
<Lib>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">amsi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
<Lib>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">amsi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
<Lib>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">amsi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
<ClCompile>
Expand All @@ -287,6 +302,9 @@
<Link>
<SubSystem Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Windows</SubSystem>
</Link>
<Lib>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">amsi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
Expand Down Expand Up @@ -324,6 +342,18 @@
<SubSystem Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Windows</SubSystem>
<SubSystem Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Windows</SubSystem>
</Link>
<Lib>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">amsi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
<Lib>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">amsi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
<Lib>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">amsi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
<Lib>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|x64'">amsi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='ReleaseStatic'">
<ClCompile>
Expand Down Expand Up @@ -365,6 +395,18 @@
<SubSystem Condition="'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'">Windows</SubSystem>
<SubSystem Condition="'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'">Windows</SubSystem>
</Link>
<Lib>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM'">amsi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
<Lib>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'">amsi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
<Lib>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'">amsi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
<Lib>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'">amsi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Fuzzing'">
<ClCompile>
Expand All @@ -385,6 +427,12 @@
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
<SubSystem>Windows</SubSystem>
</Link>
<Lib>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Fuzzing|Win32'">amsi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
<Lib>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Fuzzing|x64'">amsi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(WingetDisableTestHooks)'=='true'">
<ClCompile>
Expand Down
19 changes: 7 additions & 12 deletions src/AppInstallerCommonCore/Archive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@
#include "pch.h"
#include "Public/winget/Archive.h"

#include <amsi.h>
#include <comdef.h>
#include <fstream>
#include <vector>

namespace AppInstaller::Archive
{
using unique_pidlist_absolute = wil::unique_any<PIDLIST_ABSOLUTE, decltype(&::CoTaskMemFree), ::CoTaskMemFree>;
Expand Down Expand Up @@ -67,30 +62,30 @@ namespace AppInstaller::Archive
#endif

HRESULT hr = S_OK;
wil::com_ptr_nothrow<IUnknown> amsiContext;
wil::com_ptr_nothrow<IUnknown> amsiSession;
HAMSICONTEXT amsiContext;

Check failure on line 65 in src/AppInstallerCommonCore/Archive.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`amsi` is not a recognized word. (unrecognized-spelling)

Check failure on line 65 in src/AppInstallerCommonCore/Archive.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`HAMSICONTEXT` is not a recognized word. (unrecognized-spelling)
HAMSISESSION amsiSession;

Check failure on line 66 in src/AppInstallerCommonCore/Archive.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`HAMSISESSION` is not a recognized word. (unrecognized-spelling)

Check failure on line 66 in src/AppInstallerCommonCore/Archive.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`amsi` is not a recognized word. (unrecognized-spelling)

hr = AmsiInitialize(L"WinGet", &amsiContext);

Check failure on line 68 in src/AppInstallerCommonCore/Archive.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`Amsi` is not a recognized word. (unrecognized-spelling)

Check failure on line 68 in src/AppInstallerCommonCore/Archive.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`amsi` is not a recognized word. (unrecognized-spelling)
if (FAILED(hr))
{
return false;
}

hr = AmsiOpenSession(amsiContext.get(), &amsiSession);
hr = AmsiOpenSession(amsiContext, &amsiSession);

Check failure on line 74 in src/AppInstallerCommonCore/Archive.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`Amsi` is not a recognized word. (unrecognized-spelling)

Check failure on line 74 in src/AppInstallerCommonCore/Archive.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`amsi` is not a recognized word. (unrecognized-spelling)

Check failure on line 74 in src/AppInstallerCommonCore/Archive.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`amsi` is not a recognized word. (unrecognized-spelling)
if (FAILED(hr))
{
AmsiUninitialize(amsiContext.get());
AmsiUninitialize(amsiContext);
return false;
}

std::ifstream instream{ zipPath, std::ios::in | std::ios::binary };
std::vector<uint8_t> data{ { std::istreambuf_iterator<char>{ instream } }, std::istreambuf_iterator<char>{} };

AMSI_RESULT result = AMSI_RESULT_CLEAN;

Check failure on line 84 in src/AppInstallerCommonCore/Archive.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`AMSI` is not a recognized word. (unrecognized-spelling)
hr = AmsiScanBuffer(amsiContext.get(), data.data(), data.size(), zipPath.filename().c_str(), amsiSession.get(), &result);
hr = AmsiScanBuffer(amsiContext, data.data(), static_cast<ULONG>(data.size()), zipPath.filename().c_str(), amsiSession, &result);

AmsiCloseSession(amsiContext.get(), amsiSession.get());
AmsiUninitialize(amsiContext.get());
AmsiCloseSession(amsiContext, amsiSession);
AmsiUninitialize(amsiContext);

return SUCCEEDED(hr) && (result == AMSI_RESULT_CLEAN || result == AMSI_RESULT_NOT_DETECTED);
}
Expand Down
1 change: 1 addition & 0 deletions src/AppInstallerCommonCore/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <wincrypt.h>
#include <deliveryoptimization.h>
#include <deliveryoptimizationerrors.h>
#include <amsi.h>

#include "TraceLogging.h"

Expand Down

0 comments on commit ed21c90

Please sign in to comment.