blob: a4e3bf7aca7bbc002218c579d3e86b6aa0f74bdc [file] [log] [blame]
[email protected]f5bf1842012-02-15 02:52:261// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]9428edc2009-11-18 18:02:472// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
noelc8702c42017-03-16 08:51:195#include "extensions/browser/sandboxed_unpacker.h"
6
asargentc4fdad22015-08-28 22:44:397#include "base/base64.h"
[email protected]43c05d902013-07-10 21:27:008#include "base/bind.h"
ginkage553af3202015-02-04 12:39:099#include "base/command_line.h"
thestig18dfb7a52014-08-26 10:44:0410#include "base/files/file_util.h"
[email protected]3b63f8f42011-03-28 01:54:1511#include "base/memory/ref_counted.h"
[email protected]9428edc2009-11-18 18:02:4712#include "base/path_service.h"
[email protected]43c05d902013-07-10 21:27:0013#include "base/run_loop.h"
Jay Civelli6d0e68e2018-01-24 16:42:5314#include "base/strings/pattern.h"
[email protected]46acbf12013-06-10 18:43:4215#include "base/strings/string_util.h"
Jay Civelliea8f3df2018-01-24 05:17:3216#include "base/strings/utf_string_conversions.h"
gab273138e2016-05-11 18:09:3917#include "base/threading/thread_task_runner_handle.h"
[email protected]f3a1c642011-07-12 19:15:0318#include "base/values.h"
asargentc4fdad22015-08-28 22:44:3919#include "components/crx_file/id_util.h"
Ken Rockot61df0412019-07-26 17:12:1920#include "components/services/unzip/content/unzip_service.h"
21#include "components/services/unzip/in_process_unzipper.h"
Alex Kalugina34f8c02017-07-27 11:33:0322#include "content/public/browser/browser_thread.h"
[email protected]43c05d902013-07-10 21:27:0023#include "content/public/test/test_browser_thread_bundle.h"
24#include "content/public/test/test_utils.h"
asargent275faaa2015-01-27 23:43:2925#include "extensions/browser/extensions_test.h"
Minh X. Nguyen8803f4e2018-05-25 01:03:1026#include "extensions/browser/install/crx_install_error.h"
27#include "extensions/browser/install/sandboxed_unpacker_failure_reason.h"
[email protected]993da5e2013-03-23 21:25:1628#include "extensions/common/constants.h"
[email protected]e4452d32013-11-15 23:07:4129#include "extensions/common/extension.h"
asargent12a9cab72015-01-16 21:34:1630#include "extensions/common/extension_paths.h"
Jay Civelli6d0e68e2018-01-24 16:42:5331#include "extensions/common/manifest_constants.h"
ginkage553af3202015-02-04 12:39:0932#include "extensions/common/switches.h"
Joshua Pawlickifd01b7c2019-01-17 16:18:3433#include "extensions/common/verifier_formats.h"
Jay Civelli26a85642018-01-26 21:29:3934#include "extensions/strings/grit/extensions_strings.h"
Jay Civelliea8f3df2018-01-24 05:17:3235#include "extensions/test/test_extensions_client.h"
Jay Civellib6f2cc9c2018-03-10 01:13:5736#include "services/data_decoder/data_decoder_service.h"
Jay Civelliea8f3df2018-01-24 05:17:3237#include "services/data_decoder/public/cpp/test_data_decoder_service.h"
Ken Rockota373add2018-10-30 23:22:4238#include "services/data_decoder/public/mojom/constants.mojom.h"
Jay Civelliea8f3df2018-01-24 05:17:3239#include "services/service_manager/public/cpp/connector.h"
Jay Civellib6f2cc9c2018-03-10 01:13:5740#include "services/service_manager/public/cpp/test/test_connector_factory.h"
Minh X. Nguyen8803f4e2018-05-25 01:03:1041#include "testing/gmock/include/gmock/gmock.h"
[email protected]9428edc2009-11-18 18:02:4742#include "testing/gtest/include/gtest/gtest.h"
43#include "third_party/skia/include/core/SkBitmap.h"
asargentc4fdad22015-08-28 22:44:3944#include "third_party/zlib/google/zip.h"
Jay Civelli26a85642018-01-26 21:29:3945#include "ui/base/l10n/l10n_util.h"
[email protected]9428edc2009-11-18 18:02:4746
[email protected]f5ac2742012-07-02 17:50:5847namespace extensions {
48
Jay Civelliea8f3df2018-01-24 05:17:3249namespace {
50
51// Inserts an illegal path into the browser images returned by
52// TestExtensionsClient for any extension.
53class IllegalImagePathInserter
54 : public TestExtensionsClient::BrowserImagePathsFilter {
55 public:
56 IllegalImagePathInserter(TestExtensionsClient* client) : client_(client) {
57 client_->AddBrowserImagePathsFilter(this);
58 }
59
60 virtual ~IllegalImagePathInserter() {
61 client_->RemoveBrowserImagePathsFilter(this);
62 }
63
64 void Filter(const Extension* extension,
65 std::set<base::FilePath>* paths) override {
66 base::FilePath illegal_path =
67 base::FilePath(base::FilePath::kParentDirectory)
68 .AppendASCII(kTempExtensionName)
69 .AppendASCII("product_logo_128.png");
70 paths->insert(illegal_path);
71 }
72
73 private:
74 TestExtensionsClient* client_;
75};
76
77} // namespace
78
[email protected]f5ac2742012-07-02 17:50:5879class MockSandboxedUnpackerClient : public SandboxedUnpackerClient {
[email protected]9428edc2009-11-18 18:02:4780 public:
[email protected]43c05d902013-07-10 21:27:0081 void WaitForUnpack() {
82 scoped_refptr<content::MessageLoopRunner> runner =
83 new content::MessageLoopRunner;
84 quit_closure_ = runner->QuitClosure();
85 runner->Run();
[email protected]9428edc2009-11-18 18:02:4786 }
[email protected]5f2a4752012-04-27 22:18:5887
[email protected]43c05d902013-07-10 21:27:0088 base::FilePath temp_dir() const { return temp_dir_; }
Minh X. Nguyen8803f4e2018-05-25 01:03:1089 base::string16 unpack_error_message() const {
90 if (error_)
91 return error_->message();
92 return base::string16();
93 }
94 CrxInstallErrorType unpack_error_type() const {
95 if (error_)
96 return error_->type();
97 return CrxInstallErrorType::NONE;
98 }
99 int unpack_error_detail() const {
100 if (error_) {
101 return error_->type() == CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE
102 ? static_cast<int>(error_->sandbox_failure_detail())
103 : static_cast<int>(error_->detail());
104 }
105 return 0;
106 }
[email protected]43c05d902013-07-10 21:27:00107
Jay Civelli26a85642018-01-26 21:29:39108 void set_deleted_tracker(bool* deleted_tracker) {
109 deleted_tracker_ = deleted_tracker;
110 }
111
[email protected]43c05d902013-07-10 21:27:00112 private:
Jay Civelli26a85642018-01-26 21:29:39113 ~MockSandboxedUnpackerClient() override {
114 if (deleted_tracker_)
115 *deleted_tracker_ = true;
116 }
[email protected]43c05d902013-07-10 21:27:00117
Karandeep Bhatiaa8930652017-10-11 17:41:12118 void OnUnpackSuccess(
119 const base::FilePath& temp_dir,
120 const base::FilePath& extension_root,
121 std::unique_ptr<base::DictionaryValue> original_manifest,
122 const Extension* extension,
123 const SkBitmap& install_icon,
124 const base::Optional<int>& dnr_ruleset_checksum) override {
[email protected]43c05d902013-07-10 21:27:00125 temp_dir_ = temp_dir;
126 quit_closure_.Run();
[email protected]43c05d902013-07-10 21:27:00127 }
128
ginkage47e603e2015-02-27 08:42:41129 void OnUnpackFailure(const CrxInstallError& error) override {
Minh X. Nguyen8803f4e2018-05-25 01:03:10130 error_ = error;
ginkage553af3202015-02-04 12:39:09131 quit_closure_.Run();
[email protected]43c05d902013-07-10 21:27:00132 }
133
Minh X. Nguyen8803f4e2018-05-25 01:03:10134 base::Optional<CrxInstallError> error_;
[email protected]43c05d902013-07-10 21:27:00135 base::Closure quit_closure_;
136 base::FilePath temp_dir_;
Jay Civelli26a85642018-01-26 21:29:39137 bool* deleted_tracker_ = nullptr;
[email protected]9428edc2009-11-18 18:02:47138};
139
asargent275faaa2015-01-27 23:43:29140class SandboxedUnpackerTest : public ExtensionsTest {
[email protected]9428edc2009-11-18 18:02:47141 public:
danakjaee67172017-06-13 16:37:02142 SandboxedUnpackerTest()
Alex Clarkef0527a9b2019-01-23 10:43:25143 : ExtensionsTest(content::TestBrowserThreadBundle::IO_MAINLOOP) {
Ken Rockot10306292018-11-02 15:45:29144 test_connector_factory_.set_ignore_quit_requests(true);
145 }
Alex Kalugina34f8c02017-07-27 11:33:03146
dcheng72191812014-10-28 20:49:56147 void SetUp() override {
asargent275faaa2015-01-27 23:43:29148 ExtensionsTest::SetUp();
149 ASSERT_TRUE(extensions_dir_.CreateUniqueTempDir());
[email protected]c514acf2014-01-09 07:16:52150 in_process_utility_thread_helper_.reset(
151 new content::InProcessUtilityThreadHelper);
[email protected]9428edc2009-11-18 18:02:47152 // It will delete itself.
[email protected]f5ac2742012-07-02 17:50:58153 client_ = new MockSandboxedUnpackerClient;
asargentc4fdad22015-08-28 22:44:39154
Ken Rockot61df0412019-07-26 17:12:19155 InitSanboxedUnpacker(/*data_decode_service=*/nullptr);
156
157 // By default, we host an in-process UnzipperImpl to support any service
158 // clients. Tests may explicitly override the launch callback to prevent
159 // this.
160 unzip::SetUnzipperLaunchOverrideForTesting(
161 base::BindRepeating(&unzip::LaunchInProcessUnzipper));
Jay Civellib6f2cc9c2018-03-10 01:13:57162 }
163
164 void InitSanboxedUnpacker(
Ken Rockot61df0412019-07-26 17:12:19165 std::unique_ptr<service_manager::Service> data_decoder_service) {
Ken Rockota373add2018-10-30 23:22:42166 if (data_decoder_service) {
167 data_decoder_service_ = std::move(data_decoder_service);
168 } else {
169 data_decoder_service_ =
170 std::make_unique<data_decoder::DataDecoderService>(
171 RegisterDataDecoder());
172 }
173
Ken Rockota373add2018-10-30 23:22:42174 connector_ = test_connector_factory_.CreateConnector();
Jay Civellib6f2cc9c2018-03-10 01:13:57175
176 sandboxed_unpacker_ =
177 new SandboxedUnpacker(connector_->Clone(), Manifest::INTERNAL,
178 Extension::NO_FLAGS, extensions_dir_.GetPath(),
179 base::ThreadTaskRunnerHandle::Get(), client_);
[email protected]9428edc2009-11-18 18:02:47180 }
181
Ken Rockota373add2018-10-30 23:22:42182 service_manager::mojom::ServiceRequest RegisterDataDecoder() {
183 return test_connector_factory_.RegisterInstance(
184 data_decoder::mojom::kServiceName);
185 }
186
dcheng72191812014-10-28 20:49:56187 void TearDown() override {
Ken Rockot61df0412019-07-26 17:12:19188 unzip::SetUnzipperLaunchOverrideForTesting(base::NullCallback());
[email protected]f5ac2742012-07-02 17:50:58189 // Need to destruct SandboxedUnpacker before the message loop since
[email protected]38f285a52010-11-05 21:02:28190 // it posts a task to it.
danakjaee67172017-06-13 16:37:02191 sandboxed_unpacker_ = nullptr;
[email protected]43c05d902013-07-10 21:27:00192 base::RunLoop().RunUntilIdle();
asargent275faaa2015-01-27 23:43:29193 ExtensionsTest::TearDown();
danakjaee67172017-06-13 16:37:02194 in_process_utility_thread_helper_.reset();
[email protected]9428edc2009-11-18 18:02:47195 }
196
asargentc4fdad22015-08-28 22:44:39197 base::FilePath GetCrxFullPath(const std::string& crx_name) {
198 base::FilePath full_path;
Avi Drissman210441b72018-05-01 15:51:00199 EXPECT_TRUE(base::PathService::Get(extensions::DIR_TEST_DATA, &full_path));
asargentc4fdad22015-08-28 22:44:39200 full_path = full_path.AppendASCII("unpacker").AppendASCII(crx_name);
201 EXPECT_TRUE(base::PathExists(full_path)) << full_path.value();
202 return full_path;
203 }
204
ginkage553af3202015-02-04 12:39:09205 void SetupUnpacker(const std::string& crx_name,
206 const std::string& package_hash) {
asargentc4fdad22015-08-28 22:44:39207 base::FilePath crx_path = GetCrxFullPath(crx_name);
pranay.kumar7b7ceb182015-05-05 12:12:46208 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]43c05d902013-07-10 21:27:00209 FROM_HERE,
kylechar0686a5232019-02-19 14:10:29210 base::BindOnce(
asargentc4fdad22015-08-28 22:44:39211 &SandboxedUnpacker::StartWithCrx, sandboxed_unpacker_,
Joshua Pawlickifd01b7c2019-01-17 16:18:34212 extensions::CRXFileInfo(std::string(), crx_path, package_hash,
213 GetTestVerifierFormat())));
asargentc4fdad22015-08-28 22:44:39214 client_->WaitForUnpack();
215 }
216
217 void SetupUnpackerWithDirectory(const std::string& crx_name) {
218 base::ScopedTempDir temp_dir;
219 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
220 base::FilePath crx_path = GetCrxFullPath(crx_name);
vabr9142fe22016-09-08 13:19:22221 ASSERT_TRUE(zip::Unzip(crx_path, temp_dir.GetPath()));
asargentc4fdad22015-08-28 22:44:39222
223 std::string fake_id = crx_file::id_util::GenerateId(crx_name);
224 std::string fake_public_key;
225 base::Base64Encode(std::string(2048, 'k'), &fake_public_key);
226 base::ThreadTaskRunnerHandle::Get()->PostTask(
kylechar0686a5232019-02-19 14:10:29227 FROM_HERE, base::BindOnce(&SandboxedUnpacker::StartWithDirectory,
228 sandboxed_unpacker_, fake_id, fake_public_key,
229 temp_dir.Take()));
[email protected]43c05d902013-07-10 21:27:00230 client_->WaitForUnpack();
[email protected]9428edc2009-11-18 18:02:47231 }
232
Jay Civelliea8f3df2018-01-24 05:17:32233 bool InstallSucceeded() const { return !client_->temp_dir().empty(); }
234
235 base::FilePath GetInstallPath() const {
[email protected]b22c8af62013-07-23 23:17:02236 return client_->temp_dir().AppendASCII(kTempExtensionName);
[email protected]b0b3abd92010-04-30 17:00:09237 }
238
Minh X. Nguyen8803f4e2018-05-25 01:03:10239 base::string16 GetInstallErrorMessage() const {
240 return client_->unpack_error_message();
241 }
242
243 CrxInstallErrorType GetInstallErrorType() const {
244 return client_->unpack_error_type();
245 }
246
247 int GetInstallErrorDetail() const { return client_->unpack_error_detail(); }
ginkage553af3202015-02-04 12:39:09248
Jay Civelli26a85642018-01-26 21:29:39249 void ExpectInstallErrorContains(const std::string& error) {
Minh X. Nguyen8803f4e2018-05-25 01:03:10250 std::string full_error = base::UTF16ToUTF8(client_->unpack_error_message());
Jay Civelli26a85642018-01-26 21:29:39251 EXPECT_TRUE(full_error.find(error) != std::string::npos)
252 << "Error message " << full_error << " does not contain " << error;
253 }
254
255 // Unpacks the package |package_name| and checks that |sandboxed_unpacker_|
256 // gets deleted.
257 void TestSandboxedUnpackerDeleted(const std::string& package_name,
258 bool expect_success) {
259 bool client_deleted = false;
260 client_->set_deleted_tracker(&client_deleted);
261 SetupUnpacker(package_name, "");
Minh X. Nguyen8803f4e2018-05-25 01:03:10262 EXPECT_EQ(GetInstallErrorMessage().empty(), expect_success);
Jay Civelli26a85642018-01-26 21:29:39263 // Remove our reference to |sandboxed_unpacker_|, it should get deleted
264 // since/ it's the last reference.
265 sandboxed_unpacker_ = nullptr;
266 // The SandboxedUnpacker should have been deleted and deleted the client.
267 EXPECT_TRUE(client_deleted);
268 }
269
[email protected]9428edc2009-11-18 18:02:47270 protected:
[email protected]ea1a3f62012-11-16 20:34:23271 base::ScopedTempDir extensions_dir_;
[email protected]f5ac2742012-07-02 17:50:58272 MockSandboxedUnpackerClient* client_;
[email protected]f5ac2742012-07-02 17:50:58273 scoped_refptr<SandboxedUnpacker> sandboxed_unpacker_;
dchengf5d241082016-04-21 03:43:11274 std::unique_ptr<content::InProcessUtilityThreadHelper>
[email protected]c514acf2014-01-09 07:16:52275 in_process_utility_thread_helper_;
Ken Rockota373add2018-10-30 23:22:42276
277 service_manager::TestConnectorFactory test_connector_factory_;
Jay Civellib6f2cc9c2018-03-10 01:13:57278 std::unique_ptr<service_manager::Connector> connector_;
Ken Rockota373add2018-10-30 23:22:42279
280 std::unique_ptr<service_manager::Service> data_decoder_service_;
[email protected]9428edc2009-11-18 18:02:47281};
282
Jay Civelli26a85642018-01-26 21:29:39283TEST_F(SandboxedUnpackerTest, EmptyDefaultLocale) {
284 SetupUnpacker("empty_default_locale.crx", "");
285 ExpectInstallErrorContains(manifest_errors::kInvalidDefaultLocale);
Minh X. Nguyen8803f4e2018-05-25 01:03:10286 ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
287 GetInstallErrorType());
288 EXPECT_EQ(
289 static_cast<int>(SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED),
290 GetInstallErrorDetail());
Jay Civelli26a85642018-01-26 21:29:39291}
292
293TEST_F(SandboxedUnpackerTest, HasDefaultLocaleMissingLocalesFolder) {
294 SetupUnpacker("has_default_missing_locales.crx", "");
295 ExpectInstallErrorContains(manifest_errors::kLocalesTreeMissing);
Minh X. Nguyen8803f4e2018-05-25 01:03:10296 ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
297 GetInstallErrorType());
298 EXPECT_EQ(
299 static_cast<int>(SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED),
300 GetInstallErrorDetail());
Jay Civelli26a85642018-01-26 21:29:39301}
302
303TEST_F(SandboxedUnpackerTest, InvalidDefaultLocale) {
304 SetupUnpacker("invalid_default_locale.crx", "");
305 ExpectInstallErrorContains(manifest_errors::kInvalidDefaultLocale);
Minh X. Nguyen8803f4e2018-05-25 01:03:10306 ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
307 GetInstallErrorType());
308 EXPECT_EQ(
309 static_cast<int>(SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED),
310 GetInstallErrorDetail());
Jay Civelli26a85642018-01-26 21:29:39311}
312
313TEST_F(SandboxedUnpackerTest, MissingDefaultData) {
314 SetupUnpacker("missing_default_data.crx", "");
315 ExpectInstallErrorContains(manifest_errors::kLocalesNoDefaultMessages);
Minh X. Nguyen8803f4e2018-05-25 01:03:10316 ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
317 GetInstallErrorType());
318 EXPECT_EQ(
319 static_cast<int>(SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED),
320 GetInstallErrorDetail());
Jay Civelli26a85642018-01-26 21:29:39321}
322
323TEST_F(SandboxedUnpackerTest, MissingDefaultLocaleHasLocalesFolder) {
324 SetupUnpacker("missing_default_has_locales.crx", "");
325 ExpectInstallErrorContains(l10n_util::GetStringUTF8(
326 IDS_EXTENSION_LOCALES_NO_DEFAULT_LOCALE_SPECIFIED));
Minh X. Nguyen8803f4e2018-05-25 01:03:10327 ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
328 GetInstallErrorType());
329 EXPECT_EQ(
330 static_cast<int>(SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED),
331 GetInstallErrorDetail());
Jay Civelli26a85642018-01-26 21:29:39332}
333
334TEST_F(SandboxedUnpackerTest, MissingMessagesFile) {
335 SetupUnpacker("missing_messages_file.crx", "");
336 EXPECT_TRUE(base::MatchPattern(
Minh X. Nguyen8803f4e2018-05-25 01:03:10337 GetInstallErrorMessage(),
Jay Civelli26a85642018-01-26 21:29:39338 base::ASCIIToUTF16("*") +
339 base::ASCIIToUTF16(manifest_errors::kLocalesMessagesFileMissing) +
340 base::ASCIIToUTF16("*_locales?en_US?messages.json'.")))
Minh X. Nguyen8803f4e2018-05-25 01:03:10341 << GetInstallErrorMessage();
342 ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
343 GetInstallErrorType());
344 EXPECT_EQ(
345 static_cast<int>(SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED),
346 GetInstallErrorDetail());
Jay Civelli26a85642018-01-26 21:29:39347}
348
349TEST_F(SandboxedUnpackerTest, NoLocaleData) {
350 SetupUnpacker("no_locale_data.crx", "");
351 ExpectInstallErrorContains(manifest_errors::kLocalesNoDefaultMessages);
Minh X. Nguyen8803f4e2018-05-25 01:03:10352 ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
353 GetInstallErrorType());
354 EXPECT_EQ(
355 static_cast<int>(SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED),
356 GetInstallErrorDetail());
Jay Civelli26a85642018-01-26 21:29:39357}
358
Jay Civelliea8f3df2018-01-24 05:17:32359TEST_F(SandboxedUnpackerTest, ImageDecodingError) {
360 const char kExpected[] = "Could not decode image: ";
361 SetupUnpacker("bad_image.crx", "");
Minh X. Nguyen8803f4e2018-05-25 01:03:10362 EXPECT_TRUE(base::StartsWith(GetInstallErrorMessage(),
363 base::ASCIIToUTF16(kExpected),
Jay Civelliea8f3df2018-01-24 05:17:32364 base::CompareCase::INSENSITIVE_ASCII))
365 << "Expected prefix: \"" << kExpected << "\", actual error: \""
Minh X. Nguyen8803f4e2018-05-25 01:03:10366 << GetInstallErrorMessage() << "\"";
367 ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
368 GetInstallErrorType());
369 EXPECT_EQ(
370 static_cast<int>(SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED),
371 GetInstallErrorDetail());
Jay Civelliea8f3df2018-01-24 05:17:32372}
373
374TEST_F(SandboxedUnpackerTest, BadPathError) {
375 IllegalImagePathInserter inserter(
376 static_cast<TestExtensionsClient*>(ExtensionsClient::Get()));
377 SetupUnpacker("good_package.crx", "");
378 // Install should have failed with an error.
379 EXPECT_FALSE(InstallSucceeded());
Minh X. Nguyen8803f4e2018-05-25 01:03:10380 EXPECT_FALSE(GetInstallErrorMessage().empty());
381 ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
382 GetInstallErrorType());
383 EXPECT_EQ(static_cast<int>(
384 SandboxedUnpackerFailureReason::INVALID_PATH_FOR_BROWSER_IMAGE),
385 GetInstallErrorDetail());
Jay Civelliea8f3df2018-01-24 05:17:32386}
387
[email protected]f5ac2742012-07-02 17:50:58388TEST_F(SandboxedUnpackerTest, NoCatalogsSuccess) {
ginkage553af3202015-02-04 12:39:09389 SetupUnpacker("no_l10n.crx", "");
[email protected]9428edc2009-11-18 18:02:47390 // Check that there is no _locales folder.
asargent275faaa2015-01-27 23:43:29391 base::FilePath install_path = GetInstallPath().Append(kLocaleFolder);
[email protected]7567484142013-07-11 17:36:07392 EXPECT_FALSE(base::PathExists(install_path));
Minh X. Nguyen8803f4e2018-05-25 01:03:10393 EXPECT_EQ(CrxInstallErrorType::NONE, GetInstallErrorType());
[email protected]9428edc2009-11-18 18:02:47394}
395
asargentc4fdad22015-08-28 22:44:39396TEST_F(SandboxedUnpackerTest, FromDirNoCatalogsSuccess) {
397 SetupUnpackerWithDirectory("no_l10n.crx");
398 // Check that there is no _locales folder.
399 base::FilePath install_path = GetInstallPath().Append(kLocaleFolder);
400 EXPECT_FALSE(base::PathExists(install_path));
Minh X. Nguyen8803f4e2018-05-25 01:03:10401 EXPECT_EQ(CrxInstallErrorType::NONE, GetInstallErrorType());
asargentc4fdad22015-08-28 22:44:39402}
403
[email protected]11170a772013-12-13 11:38:32404TEST_F(SandboxedUnpackerTest, WithCatalogsSuccess) {
ginkage553af3202015-02-04 12:39:09405 SetupUnpacker("good_l10n.crx", "");
[email protected]43c05d902013-07-10 21:27:00406 // Check that there is _locales folder.
asargent275faaa2015-01-27 23:43:29407 base::FilePath install_path = GetInstallPath().Append(kLocaleFolder);
[email protected]7567484142013-07-11 17:36:07408 EXPECT_TRUE(base::PathExists(install_path));
Minh X. Nguyen8803f4e2018-05-25 01:03:10409 EXPECT_EQ(CrxInstallErrorType::NONE, GetInstallErrorType());
[email protected]9428edc2009-11-18 18:02:47410}
[email protected]f5ac2742012-07-02 17:50:58411
asargentc4fdad22015-08-28 22:44:39412TEST_F(SandboxedUnpackerTest, FromDirWithCatalogsSuccess) {
413 SetupUnpackerWithDirectory("good_l10n.crx");
414 // Check that there is _locales folder.
415 base::FilePath install_path = GetInstallPath().Append(kLocaleFolder);
416 EXPECT_TRUE(base::PathExists(install_path));
Minh X. Nguyen8803f4e2018-05-25 01:03:10417 EXPECT_EQ(CrxInstallErrorType::NONE, GetInstallErrorType());
asargentc4fdad22015-08-28 22:44:39418}
419
ginkage553af3202015-02-04 12:39:09420TEST_F(SandboxedUnpackerTest, FailHashCheck) {
421 base::CommandLine::ForCurrentProcess()->AppendSwitch(
422 extensions::switches::kEnableCrxHashCheck);
waffles5918d5f2017-05-23 01:45:28423 SetupUnpacker("good_l10n.crx", std::string(64, '0'));
ginkage553af3202015-02-04 12:39:09424 // Check that there is an error message.
Minh X. Nguyen8803f4e2018-05-25 01:03:10425 EXPECT_FALSE(GetInstallErrorMessage().empty());
426 ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
427 GetInstallErrorType());
428 EXPECT_EQ(static_cast<int>(
429 SandboxedUnpackerFailureReason::CRX_HASH_VERIFICATION_FAILED),
430 GetInstallErrorDetail());
ginkage553af3202015-02-04 12:39:09431}
432
Jay Civelli6d0e68e2018-01-24 16:42:53433TEST_F(SandboxedUnpackerTest, InvalidMessagesFile) {
434 SetupUnpackerWithDirectory("invalid_messages_file.crx");
435 // Check that there is no _locales folder.
436 base::FilePath install_path = GetInstallPath().Append(kLocaleFolder);
437 EXPECT_FALSE(base::PathExists(install_path));
438 EXPECT_TRUE(base::MatchPattern(
Minh X. Nguyen8803f4e2018-05-25 01:03:10439 GetInstallErrorMessage(),
Jay Civelli6d0e68e2018-01-24 16:42:53440 base::ASCIIToUTF16("*_locales?en_US?messages.json': Line: 2, column: 10,"
441 " Syntax error.'.")))
Minh X. Nguyen8803f4e2018-05-25 01:03:10442 << GetInstallErrorMessage();
443 ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
444 GetInstallErrorType());
445 EXPECT_EQ(static_cast<int>(
446 SandboxedUnpackerFailureReason::COULD_NOT_LOCALIZE_EXTENSION),
447 GetInstallErrorDetail());
Jay Civelli6d0e68e2018-01-24 16:42:53448}
449
ginkage553af3202015-02-04 12:39:09450TEST_F(SandboxedUnpackerTest, PassHashCheck) {
451 base::CommandLine::ForCurrentProcess()->AppendSwitch(
452 extensions::switches::kEnableCrxHashCheck);
453 SetupUnpacker(
454 "good_l10n.crx",
Devlin Cronin1de938972018-04-24 19:17:15455 "614AE3D608F4C2185E9173293AB3F93EE7C7C79C9A2C3CF71F633386A3296A6C");
ginkage553af3202015-02-04 12:39:09456 // Check that there is no error message.
Minh X. Nguyen8803f4e2018-05-25 01:03:10457 EXPECT_THAT(GetInstallErrorMessage(), testing::IsEmpty());
458 EXPECT_EQ(CrxInstallErrorType::NONE, GetInstallErrorType());
ginkage553af3202015-02-04 12:39:09459}
460
461TEST_F(SandboxedUnpackerTest, SkipHashCheck) {
462 SetupUnpacker("good_l10n.crx", "badhash");
463 // Check that there is no error message.
Minh X. Nguyen8803f4e2018-05-25 01:03:10464 EXPECT_THAT(GetInstallErrorMessage(), testing::IsEmpty());
465 EXPECT_EQ(CrxInstallErrorType::NONE, GetInstallErrorType());
ginkage553af3202015-02-04 12:39:09466}
467
Jay Civellib6f2cc9c2018-03-10 01:13:57468// The following tests simulate the utility services failling.
469TEST_F(SandboxedUnpackerTest, UnzipperServiceFails) {
Ken Rockot61df0412019-07-26 17:12:19470 // We override the Unzipper's launching behavior to drop the interface
471 // receiver, effectively simulating a crashy service process.
472 unzip::SetUnzipperLaunchOverrideForTesting(base::BindRepeating([]() -> auto {
473 mojo::PendingRemote<unzip::mojom::Unzipper> remote;
474 ignore_result(remote.InitWithNewPipeAndPassReceiver());
475 return remote;
476 }));
477
478 InitSanboxedUnpacker(/*data_decoder_service=*/nullptr);
Jay Civellib6f2cc9c2018-03-10 01:13:57479 SetupUnpacker("good_package.crx", "");
480 EXPECT_FALSE(InstallSucceeded());
Minh X. Nguyen8803f4e2018-05-25 01:03:10481 EXPECT_FALSE(GetInstallErrorMessage().empty());
482 ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
483 GetInstallErrorType());
484 EXPECT_EQ(static_cast<int>(SandboxedUnpackerFailureReason::UNZIP_FAILED),
485 GetInstallErrorDetail());
Jay Civellib6f2cc9c2018-03-10 01:13:57486}
487
488TEST_F(SandboxedUnpackerTest, JsonParserFails) {
Ken Rockot61df0412019-07-26 17:12:19489 InitSanboxedUnpacker(std::make_unique<data_decoder::CrashyDataDecoderService>(
490 RegisterDataDecoder(), /*crash_json=*/true, /*crash_image=*/false));
Jay Civellib6f2cc9c2018-03-10 01:13:57491 SetupUnpacker("good_package.crx", "");
492 EXPECT_FALSE(InstallSucceeded());
Minh X. Nguyen8803f4e2018-05-25 01:03:10493 EXPECT_FALSE(GetInstallErrorMessage().empty());
494 ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
495 GetInstallErrorType());
Jay Civellib6f2cc9c2018-03-10 01:13:57496}
497
498TEST_F(SandboxedUnpackerTest, ImageDecoderFails) {
Ken Rockot61df0412019-07-26 17:12:19499 InitSanboxedUnpacker(std::make_unique<data_decoder::CrashyDataDecoderService>(
500 RegisterDataDecoder(), /*crash_json=*/false, /*crash_image=*/true));
Jay Civellib6f2cc9c2018-03-10 01:13:57501 SetupUnpacker("good_package.crx", "");
502 EXPECT_FALSE(InstallSucceeded());
Minh X. Nguyen8803f4e2018-05-25 01:03:10503 EXPECT_FALSE(GetInstallErrorMessage().empty());
504 ASSERT_EQ(CrxInstallErrorType::SANDBOXED_UNPACKER_FAILURE,
505 GetInstallErrorType());
506 EXPECT_EQ(
507 static_cast<int>(SandboxedUnpackerFailureReason::
508 UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL),
509 GetInstallErrorDetail());
Jay Civellib6f2cc9c2018-03-10 01:13:57510}
511
Jay Civelli26a85642018-01-26 21:29:39512// SandboxedUnpacker is ref counted and is reference by callbacks and
513// InterfacePtrs. This tests that it gets deleted as expected (so that no extra
514// refs are left).
515TEST_F(SandboxedUnpackerTest, DeletedOnSuccess) {
516 TestSandboxedUnpackerDeleted("good_l10n.crx", /*expect_success=*/true);
517}
518
519TEST_F(SandboxedUnpackerTest, DeletedOnFailure) {
520 TestSandboxedUnpackerDeleted("bad_image.crx", /*expect_success=*/false);
521}
522
[email protected]f5ac2742012-07-02 17:50:58523} // namespace extensions