summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorasargent <asargent@chromium.org>2014-10-09 14:27:57 -0700
committerCommit bot <commit-bot@chromium.org>2014-10-09 21:28:17 +0000
commit7cc29ce343a235f9067545ddd19ba2d982c4595f (patch)
tree7245596bfb1ab50817302de6fea3c2a781bfecea
parentf7bcf0f223a64972ba7b4f53d0c618d9649a882b (diff)
downloadchromium_src-7cc29ce343a235f9067545ddd19ba2d982c4595f.zip
chromium_src-7cc29ce343a235f9067545ddd19ba2d982c4595f.tar.gz
chromium_src-7cc29ce343a235f9067545ddd19ba2d982c4595f.tar.bz2
Fix extension content verification handling of ./ in icon paths
When extension manifests contain icon paths with a leading ./, we were failing to process them properly BUG=410666 Review URL: https://codereview.chromium.org/630243002 Cr-Commit-Position: refs/heads/master@{#298979}
-rw-r--r--chrome/browser/extensions/content_verifier_browsertest.cc122
-rw-r--r--chrome/test/data/extensions/content_verifier/dot_slash_paths.crxbin0 -> 7074 bytes
-rw-r--r--chrome/test/data/extensions/content_verifier/dot_slash_paths/_metadata/verified_contents.json1
-rw-r--r--chrome/test/data/extensions/content_verifier/dot_slash_paths/background.js9
-rw-r--r--chrome/test/data/extensions/content_verifier/dot_slash_paths/dir/page2.html2
-rw-r--r--chrome/test/data/extensions/content_verifier/dot_slash_paths/icon.pngbin0 -> 524 bytes
-rw-r--r--chrome/test/data/extensions/content_verifier/dot_slash_paths/icon2.pngbin0 -> 515 bytes
-rw-r--r--chrome/test/data/extensions/content_verifier/dot_slash_paths/icon3.pngbin0 -> 549 bytes
-rw-r--r--chrome/test/data/extensions/content_verifier/dot_slash_paths/img/test/icon4.pngbin0 -> 516 bytes
-rw-r--r--chrome/test/data/extensions/content_verifier/dot_slash_paths/img/test/icon5.pngbin0 -> 494 bytes
-rw-r--r--chrome/test/data/extensions/content_verifier/dot_slash_paths/manifest.json19
-rw-r--r--chrome/test/data/extensions/content_verifier/dot_slash_paths/page.html1
-rw-r--r--chrome/test/data/extensions/content_verifier/dot_slash_paths/page.js6
-rw-r--r--chrome/test/data/extensions/content_verifier/dot_slash_paths/page2.js6
-rw-r--r--extensions/browser/content_verifier.cc39
-rw-r--r--extensions/browser/content_verifier_io_data.cc5
-rw-r--r--extensions/browser/content_verifier_io_data.h4
-rw-r--r--extensions/browser/content_verify_job.cc16
-rw-r--r--extensions/browser/content_verify_job.h11
19 files changed, 227 insertions, 14 deletions
diff --git a/chrome/browser/extensions/content_verifier_browsertest.cc b/chrome/browser/extensions/content_verifier_browsertest.cc
index c6ebcd9..1b7bf2a 100644
--- a/chrome/browser/extensions/content_verifier_browsertest.cc
+++ b/chrome/browser/extensions/content_verifier_browsertest.cc
@@ -87,6 +87,82 @@ class JobDelegate : public ContentVerifyJob::TestDelegate {
bool fail_next_done_;
};
+class JobObserver : public ContentVerifyJob::TestObserver {
+ public:
+ JobObserver();
+ virtual ~JobObserver();
+
+ // Call this to add an expected job result.
+ void ExpectJobResult(const std::string& extension_id,
+ const base::FilePath& relative_path,
+ bool expected_to_fail);
+
+ // Wait to see expected jobs. Returns true if we saw all jobs finish as
+ // expected, or false if any job completed with non-expected success/failure
+ // status.
+ bool WaitForExpectedJobs();
+
+ // ContentVerifyJob::TestObserver interface
+ virtual void JobStarted(const std::string& extension_id,
+ const base::FilePath& relative_path) OVERRIDE;
+
+ virtual void JobFinished(const std::string& extension_id,
+ const base::FilePath& relative_path,
+ bool failed) OVERRIDE;
+
+ private:
+ typedef std::pair<std::string, base::FilePath> ExtensionFile;
+ typedef std::map<ExtensionFile, bool> ExpectedJobs;
+ ExpectedJobs expected_jobs_;
+ scoped_refptr<content::MessageLoopRunner> loop_runner_;
+ bool saw_expected_job_results_;
+};
+
+void JobObserver::ExpectJobResult(const std::string& extension_id,
+ const base::FilePath& relative_path,
+ bool expected_to_fail) {
+ expected_jobs_.insert(std::make_pair(
+ ExtensionFile(extension_id, relative_path), expected_to_fail));
+}
+
+JobObserver::JobObserver() : saw_expected_job_results_(false) {
+}
+
+JobObserver::~JobObserver() {
+}
+
+bool JobObserver::WaitForExpectedJobs() {
+ if (!expected_jobs_.empty()) {
+ loop_runner_ = new content::MessageLoopRunner();
+ loop_runner_->Run();
+ }
+ return saw_expected_job_results_;
+}
+
+void JobObserver::JobStarted(const std::string& extension_id,
+ const base::FilePath& relative_path) {
+}
+
+void JobObserver::JobFinished(const std::string& extension_id,
+ const base::FilePath& relative_path,
+ bool failed) {
+ ExpectedJobs::iterator i = expected_jobs_.find(ExtensionFile(
+ extension_id, relative_path.NormalizePathSeparatorsTo('/')));
+ if (i != expected_jobs_.end()) {
+ if (failed != i->second) {
+ saw_expected_job_results_ = false;
+ if (loop_runner_.get())
+ loop_runner_->Quit();
+ }
+ expected_jobs_.erase(i);
+ if (expected_jobs_.empty()) {
+ saw_expected_job_results_ = true;
+ if (loop_runner_.get())
+ loop_runner_->Quit();
+ }
+ }
+}
+
} // namespace
class ContentVerifierTest : public ExtensionBrowserTest {
@@ -104,6 +180,15 @@ class ContentVerifierTest : public ExtensionBrowserTest {
// Setup our unload observer and JobDelegate, and install a test extension.
virtual void SetUpOnMainThread() override {
ExtensionBrowserTest::SetUpOnMainThread();
+ }
+
+ virtual void TearDownOnMainThread() override {
+ ContentVerifyJob::SetDelegateForTests(NULL);
+ ContentVerifyJob::SetObserverForTests(NULL);
+ ExtensionBrowserTest::TearDownOnMainThread();
+ }
+
+ virtual void OpenPageAndWaitForUnload() {
unload_observer_.reset(
new UnloadObserver(ExtensionRegistry::Get(profile())));
const Extension* extension = InstallExtensionFromWebstore(
@@ -113,14 +198,6 @@ class ContentVerifierTest : public ExtensionBrowserTest {
page_url_ = extension->GetResourceURL("page.html");
delegate_.set_id(id_);
ContentVerifyJob::SetDelegateForTests(&delegate_);
- }
-
- virtual void TearDownOnMainThread() override {
- ContentVerifyJob::SetDelegateForTests(NULL);
- ExtensionBrowserTest::TearDownOnMainThread();
- }
-
- virtual void OpenPageAndWaitForUnload() {
AddTabAtIndex(1, page_url_, ui::PAGE_TRANSITION_LINK);
unload_observer_->WaitForUnload(id_);
ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
@@ -149,4 +226,33 @@ IN_PROC_BROWSER_TEST_F(ContentVerifierTest, FailOnDone) {
OpenPageAndWaitForUnload();
}
+IN_PROC_BROWSER_TEST_F(ContentVerifierTest, DotSlashPaths) {
+ JobObserver job_observer;
+ ContentVerifyJob::SetObserverForTests(&job_observer);
+ std::string id = "hoipipabpcoomfapcecilckodldhmpgl";
+
+ job_observer.ExpectJobResult(
+ id, base::FilePath(FILE_PATH_LITERAL("background.js")), false);
+ job_observer.ExpectJobResult(
+ id, base::FilePath(FILE_PATH_LITERAL("page.html")), false);
+ job_observer.ExpectJobResult(
+ id, base::FilePath(FILE_PATH_LITERAL("page.js")), false);
+ job_observer.ExpectJobResult(
+ id, base::FilePath(FILE_PATH_LITERAL("dir/page2.html")), false);
+ job_observer.ExpectJobResult(
+ id, base::FilePath(FILE_PATH_LITERAL("page2.js")), false);
+
+ // Install a test extension we copied from the webstore that has actual
+ // signatures, and contains image paths with leading "./".
+ const Extension* extension = InstallExtensionFromWebstore(
+ test_data_dir_.AppendASCII("content_verifier/dot_slash_paths.crx"), 1);
+
+ ASSERT_TRUE(extension);
+ ASSERT_EQ(extension->id(), id);
+
+ EXPECT_TRUE(job_observer.WaitForExpectedJobs());
+
+ ContentVerifyJob::SetObserverForTests(NULL);
+}
+
} // namespace extensions
diff --git a/chrome/test/data/extensions/content_verifier/dot_slash_paths.crx b/chrome/test/data/extensions/content_verifier/dot_slash_paths.crx
new file mode 100644
index 0000000..f7ec7fb
--- /dev/null
+++ b/chrome/test/data/extensions/content_verifier/dot_slash_paths.crx
Binary files differ
diff --git a/chrome/test/data/extensions/content_verifier/dot_slash_paths/_metadata/verified_contents.json b/chrome/test/data/extensions/content_verifier/dot_slash_paths/_metadata/verified_contents.json
new file mode 100644
index 0000000..9e2927d
--- /dev/null
+++ b/chrome/test/data/extensions/content_verifier/dot_slash_paths/_metadata/verified_contents.json
@@ -0,0 +1 @@
+[{"description":"treehash per file","signed_content":{"payload":"eyJjb250ZW50X2hhc2hlcyI6W3siYmxvY2tfc2l6ZSI6NDA5NiwiZGlnZXN0Ijoic2hhMjU2IiwiZmlsZXMiOlt7InBhdGgiOiJiYWNrZ3JvdW5kLmpzIiwicm9vdF9oYXNoIjoidnZESEk3ZWFVdUYyWElGNzdjNE9vSk9pc0NTNFVoYmFtbTRVQTlLSS0yTSJ9LHsicGF0aCI6ImRpci9wYWdlMi5odG1sIiwicm9vdF9oYXNoIjoiVGNvanllU2xHMlpVOXQ4elVwVzJvQVp4cGlnb0FlZThMZkZZQmdJWWxzcyJ9LHsicGF0aCI6Imljb24ucG5nIiwicm9vdF9oYXNoIjoiWDdrMEFjLXJuc0NDc2ZteTJxejFRRnlWNnRtVkIyVUd0QmNDRDdrTHo2SSJ9LHsicGF0aCI6Imljb24yLnBuZyIsInJvb3RfaGFzaCI6ImlFc2xCdmd2dTVEaXcwbVM0enR6TVd5QnZSUGZJQkpjeS04QnJreEp0ZTgifSx7InBhdGgiOiJpY29uMy5wbmciLCJyb290X2hhc2giOiJiRWZMU1JmYWd3MlBGeGJfZDM3R1RtaV90Y3ZwMTdraHdubHQzcmhBQkgwIn0seyJwYXRoIjoiaW1nL3Rlc3QvaWNvbjQucG5nIiwicm9vdF9oYXNoIjoieWQxUV9xMGVSb21UZE5BQll1UVpaUFg1ZXlXN3JpZ0hWSzdhVWdNTHBJdyJ9LHsicGF0aCI6ImltZy90ZXN0L2ljb241LnBuZyIsInJvb3RfaGFzaCI6InhxUGdOQXU5RW1YQ25Td0xtTk9VZGZkX19CZENCN0o4SWM2WHcxNXRSeFUifSx7ImNhbm9uaWNhbF9qc29uX3Jvb3RfaGFzaCI6InczaHhzeUpJZ3ZLN2RaM1ZfSGdZWkpJZkEzLW5ReXhNYkduMTNnazIzT00iLCJwYXRoIjoibWFuaWZlc3QuanNvbiIsInJvb3RfaGFzaCI6ImhOdE1vSC1fUnRCY2U0TkVibG1sYW1ycUttTW4wNWFOdlQwZ2dBaHBqX1UifSx7InBhdGgiOiJwYWdlLmh0bWwiLCJyb290X2hhc2giOiJNQlhPN0s3aXdzaHByamdLbERjVGRXRXViVlJ6bENNbXF3N1dTZUNSMkRzIn0seyJwYXRoIjoicGFnZS5qcyIsInJvb3RfaGFzaCI6IjNWQnFaUG5iWXVZblBKaTZMeVRzenJZVDh1MjRXNkFNTWZDVkNQRlhuSzQifSx7InBhdGgiOiJwYWdlMi5qcyIsInJvb3RfaGFzaCI6IlRtaV9JM0w1UkdsYWRDMlk0OXZZNllENmhndzh5aXdvc215ZXJUREVVNEEifV0sImZvcm1hdCI6InRyZWVoYXNoIiwiaGFzaF9ibG9ja19zaXplIjo0MDk2fV0sIml0ZW1faWQiOiJob2lwaXBhYnBjb29tZmFwY2VjaWxja29kbGRobXBnbCIsIml0ZW1fdmVyc2lvbiI6IjAuOCIsInByb3RvY29sX3ZlcnNpb24iOjF9","signatures":[{"header":{"kid":"publisher"},"protected":"eyJhbGciOiJSUzI1NiJ9","signature":"nsuqgedzxEY0hfCqN9xHmKrIhXgIFljzTg8hFTiOnh2HhKr3I1HwhcBDbVSQ9Q0sYXW-lQTXHWR8cfcwABk4UbSQfhBa2Z2y9qoe-nyApf49anPVPG2SHbtBujYPF9qjSL0uGQpOFUSvICTiaEHl5pTUv1DvMOyiQ17JytqHaHF_towTgbSq-_b_D_8sK755S58L0BuJUhc31EJZ5llIwA1BlC8omQDpbch8QSzUQ6E0lLzK7MVkQRhVeK4bo5iMkbkQhPoTJDDFzAYwN2eafucfaZSWAADzhEp5oZbof-2QPzsuBkdOPD3F-LJ0cZ7JnW8shm1d6J9kD9PKxcreFw"},{"header":{"kid":"webstore"},"protected":"eyJhbGciOiJSUzI1NiJ9","signature":"CTCIYz86Sh043zJuIpW246A1IH64nZ2mc8zFZk4JqlWNBrkzQi38QRmSM5fKtwGPRjxLKXLsJ1LMV4HRIQHbAAJ3r4DoGF85vpJ3YgnAmFLt3uEfKC4qu8SWDVY5Ad5vZbGf1BjvTljqZJVqPjEvSQmWaNYqTKQs_3Sviil994Nq6M9tChkcQzUjZOBQSz0MTBXeYtSkla80V13VvUJ204vv_hIg0GW3x0opQ70r8qXa25aEB1zPNUavi844IgUM5fdLirMprYCjxn47Qby7MxEIchX3b9cQDiOhqFcqluD5b_s3e3fXTkAaHnc4e5GSv2SPZb10GQH97U-_5gC8tw"}]}}] \ No newline at end of file
diff --git a/chrome/test/data/extensions/content_verifier/dot_slash_paths/background.js b/chrome/test/data/extensions/content_verifier/dot_slash_paths/background.js
new file mode 100644
index 0000000..e8fd254
--- /dev/null
+++ b/chrome/test/data/extensions/content_verifier/dot_slash_paths/background.js
@@ -0,0 +1,9 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+chrome.tabs.create({url:"./page.html"});
+chrome.tabs.create({url:"dir/page2.html"});
+
+if (chrome.test)
+ chrome.test.sendMessage("background ok");
diff --git a/chrome/test/data/extensions/content_verifier/dot_slash_paths/dir/page2.html b/chrome/test/data/extensions/content_verifier/dot_slash_paths/dir/page2.html
new file mode 100644
index 0000000..a6aeb6c
--- /dev/null
+++ b/chrome/test/data/extensions/content_verifier/dot_slash_paths/dir/page2.html
@@ -0,0 +1,2 @@
+
+<script src="../page2.js"></script>
diff --git a/chrome/test/data/extensions/content_verifier/dot_slash_paths/icon.png b/chrome/test/data/extensions/content_verifier/dot_slash_paths/icon.png
new file mode 100644
index 0000000..88d7762
--- /dev/null
+++ b/chrome/test/data/extensions/content_verifier/dot_slash_paths/icon.png
Binary files differ
diff --git a/chrome/test/data/extensions/content_verifier/dot_slash_paths/icon2.png b/chrome/test/data/extensions/content_verifier/dot_slash_paths/icon2.png
new file mode 100644
index 0000000..64f52e2
--- /dev/null
+++ b/chrome/test/data/extensions/content_verifier/dot_slash_paths/icon2.png
Binary files differ
diff --git a/chrome/test/data/extensions/content_verifier/dot_slash_paths/icon3.png b/chrome/test/data/extensions/content_verifier/dot_slash_paths/icon3.png
new file mode 100644
index 0000000..93b2155
--- /dev/null
+++ b/chrome/test/data/extensions/content_verifier/dot_slash_paths/icon3.png
Binary files differ
diff --git a/chrome/test/data/extensions/content_verifier/dot_slash_paths/img/test/icon4.png b/chrome/test/data/extensions/content_verifier/dot_slash_paths/img/test/icon4.png
new file mode 100644
index 0000000..160fb7c
--- /dev/null
+++ b/chrome/test/data/extensions/content_verifier/dot_slash_paths/img/test/icon4.png
Binary files differ
diff --git a/chrome/test/data/extensions/content_verifier/dot_slash_paths/img/test/icon5.png b/chrome/test/data/extensions/content_verifier/dot_slash_paths/img/test/icon5.png
new file mode 100644
index 0000000..cc63de6
--- /dev/null
+++ b/chrome/test/data/extensions/content_verifier/dot_slash_paths/img/test/icon5.png
Binary files differ
diff --git a/chrome/test/data/extensions/content_verifier/dot_slash_paths/manifest.json b/chrome/test/data/extensions/content_verifier/dot_slash_paths/manifest.json
new file mode 100644
index 0000000..20f715b
--- /dev/null
+++ b/chrome/test/data/extensions/content_verifier/dot_slash_paths/manifest.json
@@ -0,0 +1,19 @@
+{
+"update_url": "https://clients2.google.com/service/update2/crx",
+
+ "name": "Content Verification ./ paths Test",
+ "version": "0.8",
+ "manifest_version": 2,
+ "background": {
+ "scripts": ["./background.js"]
+ },
+ "icons": {
+ "128": "./icon.png",
+ "64": "/icon2.png",
+ "32": "img/test/icon4.png",
+ "16": "./img/test/icon5.png"
+ },
+ "browser_action": {
+ "default_icon": "./icon3.png"
+ }
+}
diff --git a/chrome/test/data/extensions/content_verifier/dot_slash_paths/page.html b/chrome/test/data/extensions/content_verifier/dot_slash_paths/page.html
new file mode 100644
index 0000000..dcb3248f
--- /dev/null
+++ b/chrome/test/data/extensions/content_verifier/dot_slash_paths/page.html
@@ -0,0 +1 @@
+<script src="./page.js"></script>
diff --git a/chrome/test/data/extensions/content_verifier/dot_slash_paths/page.js b/chrome/test/data/extensions/content_verifier/dot_slash_paths/page.js
new file mode 100644
index 0000000..d5a1e69
--- /dev/null
+++ b/chrome/test/data/extensions/content_verifier/dot_slash_paths/page.js
@@ -0,0 +1,6 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+if (chrome.test)
+ chrome.test.sendMessage("page ok");
diff --git a/chrome/test/data/extensions/content_verifier/dot_slash_paths/page2.js b/chrome/test/data/extensions/content_verifier/dot_slash_paths/page2.js
new file mode 100644
index 0000000..9eb5b1d
--- /dev/null
+++ b/chrome/test/data/extensions/content_verifier/dot_slash_paths/page2.js
@@ -0,0 +1,6 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+if (chrome.test)
+ chrome.test.sendMessage("page2 ok");
diff --git a/extensions/browser/content_verifier.cc b/extensions/browser/content_verifier.cc
index 9418fe3..8c05f12 100644
--- a/extensions/browser/content_verifier.cc
+++ b/extensions/browser/content_verifier.cc
@@ -8,6 +8,7 @@
#include "base/files/file_path.h"
#include "base/stl_util.h"
+#include "base/strings/string_util.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/content_hash_fetcher.h"
#include "extensions/browser/content_hash_reader.h"
@@ -107,6 +108,28 @@ void ContentVerifier::VerifyFailed(const std::string& extension_id,
}
}
+static base::FilePath MakeImagePathRelative(const base::FilePath& path) {
+ if (path.ReferencesParent())
+ return base::FilePath();
+
+ std::vector<base::FilePath::StringType> parts;
+ path.GetComponents(&parts);
+ if (parts.empty())
+ return base::FilePath();
+
+ // Remove the first component if it is '.' or '/' or '//'.
+ const base::FilePath::StringType separators(
+ base::FilePath::kSeparators, base::FilePath::kSeparatorsLength);
+ if (!parts[0].empty() &&
+ (parts[0] == base::FilePath::kCurrentDirectory ||
+ parts[0].find_first_not_of(separators) == std::string::npos))
+ parts.erase(parts.begin());
+
+ // Note that elsewhere we always normalize path separators to '/' so this
+ // should work for all platforms.
+ return base::FilePath(JoinString(parts, '/'));
+}
+
void ContentVerifier::OnExtensionLoaded(
content::BrowserContext* browser_context,
const Extension* extension) {
@@ -115,9 +138,21 @@ void ContentVerifier::OnExtensionLoaded(
ContentVerifierDelegate::Mode mode = delegate_->ShouldBeVerified(*extension);
if (mode != ContentVerifierDelegate::NONE) {
+ // The browser image paths from the extension may not be relative (eg
+ // they might have leading '/' or './'), so we strip those to make
+ // comparing to actual relative paths work later on.
+ std::set<base::FilePath> original_image_paths =
+ delegate_->GetBrowserImagePaths(extension);
+
+ scoped_ptr<std::set<base::FilePath>> image_paths(
+ new std::set<base::FilePath>);
+ for (const auto& path : original_image_paths) {
+ image_paths->insert(MakeImagePathRelative(path));
+ }
+
scoped_ptr<ContentVerifierIOData::ExtensionData> data(
new ContentVerifierIOData::ExtensionData(
- delegate_->GetBrowserImagePaths(extension),
+ image_paths.Pass(),
extension->version() ? *extension->version() : base::Version()));
content::BrowserThread::PostTask(content::BrowserThread::IO,
FROM_HERE,
@@ -196,7 +231,7 @@ bool ContentVerifier::ShouldVerifyAnyPaths(
if (!data)
return false;
- const std::set<base::FilePath>& browser_images = data->browser_image_paths;
+ const std::set<base::FilePath>& browser_images = *(data->browser_image_paths);
base::FilePath locales_dir = extension_root.Append(kLocaleFolder);
scoped_ptr<std::set<std::string> > all_locales;
diff --git a/extensions/browser/content_verifier_io_data.cc b/extensions/browser/content_verifier_io_data.cc
index e797488..102c95b 100644
--- a/extensions/browser/content_verifier_io_data.cc
+++ b/extensions/browser/content_verifier_io_data.cc
@@ -9,9 +9,9 @@
namespace extensions {
ContentVerifierIOData::ExtensionData::ExtensionData(
- const std::set<base::FilePath>& browser_image_paths,
+ scoped_ptr<std::set<base::FilePath>> browser_image_paths,
const base::Version& version) {
- this->browser_image_paths = browser_image_paths;
+ this->browser_image_paths = browser_image_paths.Pass();
this->version = version;
}
@@ -27,6 +27,7 @@ ContentVerifierIOData::~ContentVerifierIOData() {
void ContentVerifierIOData::AddData(const std::string& extension_id,
scoped_ptr<ExtensionData> data) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ CHECK(data->browser_image_paths.get());
data_map_[extension_id] = linked_ptr<ExtensionData>(data.release());
}
diff --git a/extensions/browser/content_verifier_io_data.h b/extensions/browser/content_verifier_io_data.h
index 64596f5..92e8248 100644
--- a/extensions/browser/content_verifier_io_data.h
+++ b/extensions/browser/content_verifier_io_data.h
@@ -23,10 +23,10 @@ class ContentVerifierIOData
: public base::RefCountedThreadSafe<ContentVerifierIOData> {
public:
struct ExtensionData {
- std::set<base::FilePath> browser_image_paths;
+ scoped_ptr<std::set<base::FilePath>> browser_image_paths;
base::Version version;
- ExtensionData(const std::set<base::FilePath>& browser_image_paths,
+ ExtensionData(scoped_ptr<std::set<base::FilePath>> browser_image_paths,
const base::Version& version);
~ExtensionData();
};
diff --git a/extensions/browser/content_verify_job.cc b/extensions/browser/content_verify_job.cc
index e7e8cab..651dcae 100644
--- a/extensions/browser/content_verify_job.cc
+++ b/extensions/browser/content_verify_job.cc
@@ -20,6 +20,7 @@ namespace extensions {
namespace {
ContentVerifyJob::TestDelegate* g_test_delegate = NULL;
+ContentVerifyJob::TestObserver* g_test_observer = NULL;
class ScopedElapsedTimer {
public:
@@ -60,6 +61,9 @@ ContentVerifyJob::~ContentVerifyJob() {
void ContentVerifyJob::Start() {
DCHECK(thread_checker_.CalledOnValidThread());
+ if (g_test_observer)
+ g_test_observer->JobStarted(hash_reader_->extension_id(),
+ hash_reader_->relative_path());
base::PostTaskAndReplyWithResult(
content::BrowserThread::GetBlockingPool(),
FROM_HERE,
@@ -130,6 +134,10 @@ void ContentVerifyJob::DoneReading() {
done_reading_ = true;
if (hashes_ready_ && !FinishBlock())
DispatchFailureCallback(HASH_MISMATCH);
+
+ if (!failed_ && g_test_observer)
+ g_test_observer->JobFinished(
+ hash_reader_->extension_id(), hash_reader_->relative_path(), failed_);
}
bool ContentVerifyJob::FinishBlock() {
@@ -182,6 +190,11 @@ void ContentVerifyJob::SetDelegateForTests(TestDelegate* delegate) {
g_test_delegate = delegate;
}
+// static
+void ContentVerifyJob::SetObserverForTests(TestObserver* observer) {
+ g_test_observer = observer;
+}
+
void ContentVerifyJob::DispatchFailureCallback(FailureReason reason) {
DCHECK(!failed_);
failed_ = true;
@@ -192,6 +205,9 @@ void ContentVerifyJob::DispatchFailureCallback(FailureReason reason) {
failure_callback_.Run(reason);
failure_callback_.Reset();
}
+ if (g_test_observer)
+ g_test_observer->JobFinished(
+ hash_reader_->extension_id(), hash_reader_->relative_path(), failed_);
}
} // namespace extensions
diff --git a/extensions/browser/content_verify_job.h b/extensions/browser/content_verify_job.h
index 3ec9f85..67b7f05 100644
--- a/extensions/browser/content_verify_job.h
+++ b/extensions/browser/content_verify_job.h
@@ -78,7 +78,18 @@ class ContentVerifyJob : public base::RefCountedThreadSafe<ContentVerifyJob> {
virtual FailureReason DoneReading(const std::string& extension_id) = 0;
};
+ class TestObserver {
+ public:
+ virtual void JobStarted(const std::string& extension_id,
+ const base::FilePath& relative_path) = 0;
+
+ virtual void JobFinished(const std::string& extension_id,
+ const base::FilePath& relative_path,
+ bool failed) = 0;
+ };
+
static void SetDelegateForTests(TestDelegate* delegate);
+ static void SetObserverForTests(TestObserver* observer);
private:
DISALLOW_COPY_AND_ASSIGN(ContentVerifyJob);