// Copyright 2022 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "components/update_client/unpacker.h" #include #include #include #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/functional/bind.h" #include "base/functional/callback.h" #include "base/run_loop.h" #include "base/test/bind.h" #include "base/test/task_environment.h" #include "components/crx_file/crx_verifier.h" #include "components/services/unzip/in_process_unzipper.h" #include "components/update_client/test_configurator.h" #include "components/update_client/test_utils.h" #include "components/update_client/unzip/unzip_impl.h" #include "components/update_client/unzipper.h" #include "testing/gtest/include/gtest/gtest.h" namespace update_client { class UnpackerTest : public testing::Test { public: UnpackerTest() = default; ~UnpackerTest() override = default; void UnpackComplete(const Unpacker::Result& result); protected: base::test::TaskEnvironment env_; }; TEST_F(UnpackerTest, UnpackFullCrx) { SEQUENCE_CHECKER(sequence_checker); base::RunLoop loop; Unpacker::Unpack( std::vector(std::begin(jebg_hash), std::end(jebg_hash)), GetTestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"), base::MakeRefCounted( base::BindRepeating(&unzip::LaunchInProcessUnzipper)) ->Create(), crx_file::VerifierFormat::CRX3, base::BindLambdaForTesting([&](const Unpacker::Result& result) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker); EXPECT_EQ(result.error, UnpackerError::kNone); EXPECT_EQ(result.extended_error, 0); base::FilePath unpack_path = result.unpack_path; EXPECT_TRUE(base::DirectoryExists(unpack_path)); EXPECT_EQ(result.public_key, jebg_public_key); int64_t file_size = 0; EXPECT_TRUE(base::GetFileSize(unpack_path.AppendASCII("component1.dll"), &file_size)); EXPECT_EQ(file_size, 1024); EXPECT_TRUE(base::GetFileSize(unpack_path.AppendASCII("manifest.json"), &file_size)); EXPECT_EQ(file_size, 169); EXPECT_TRUE(base::DeletePathRecursively(unpack_path)); loop.Quit(); })); loop.Run(); } TEST_F(UnpackerTest, UnpackFileNotFound) { SEQUENCE_CHECKER(sequence_checker); base::RunLoop loop; Unpacker::Unpack( std::vector(std::begin(jebg_hash), std::end(jebg_hash)), GetTestFilePath("file_not_found.crx"), nullptr, crx_file::VerifierFormat::CRX3, base::BindLambdaForTesting([&](const Unpacker::Result& result) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker); EXPECT_EQ(result.error, UnpackerError::kInvalidFile); EXPECT_EQ(result.extended_error, static_cast( crx_file::VerifierResult::ERROR_FILE_NOT_READABLE)); EXPECT_TRUE(result.unpack_path.empty()); EXPECT_TRUE(result.public_key.empty()); loop.Quit(); })); loop.Run(); } // Tests a mismatch between the public key hash and the id of the component. TEST_F(UnpackerTest, UnpackFileHashMismatch) { SEQUENCE_CHECKER(sequence_checker); base::RunLoop loop; Unpacker::Unpack( std::vector(std::begin(abag_hash), std::end(abag_hash)), GetTestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"), nullptr, crx_file::VerifierFormat::CRX3, base::BindLambdaForTesting([&](const Unpacker::Result& result) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker); EXPECT_EQ(result.error, UnpackerError::kInvalidFile); EXPECT_EQ(result.extended_error, static_cast( crx_file::VerifierResult::ERROR_REQUIRED_PROOF_MISSING)); EXPECT_TRUE(result.unpack_path.empty()); EXPECT_TRUE(result.public_key.empty()); loop.Quit(); })); loop.Run(); } TEST_F(UnpackerTest, UnpackWithVerifiedContents) { SEQUENCE_CHECKER(sequence_checker); base::RunLoop loop; Unpacker::Unpack( std::vector(), GetTestFilePath("gndmhdcefbhlchkhipcnnbkcmicncehk_22_314.crx3"), base::MakeRefCounted( base::BindRepeating(&unzip::LaunchInProcessUnzipper)) ->Create(), crx_file::VerifierFormat::CRX3, base::BindLambdaForTesting([&](const Unpacker::Result& result) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker); EXPECT_EQ(result.error, UnpackerError::kNone); base::FilePath unpack_path = result.unpack_path; EXPECT_FALSE(unpack_path.empty()); EXPECT_TRUE(base::DirectoryExists(unpack_path)); int64_t file_size = 0; EXPECT_TRUE(base::GetFileSize( unpack_path.AppendASCII("_metadata/verified_contents.json"), &file_size)); EXPECT_EQ(file_size, 1538); EXPECT_TRUE(base::DeletePathRecursively(unpack_path)); loop.Quit(); })); loop.Run(); } } // namespace update_client