OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/android/webapk/webapk_icon_hasher.h" | 5 #include "chrome/browser/android/webapk/webapk_icon_hasher.h" |
6 | 6 |
7 #include "base/strings/string_number_conversions.h" | 7 #include "base/strings/string_number_conversions.h" |
8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
9 #include "base/threading/thread_task_runner_handle.h" | 9 #include "base/threading/thread_task_runner_handle.h" |
10 #include "net/base/data_url.h" | 10 #include "net/base/data_url.h" |
11 #include "net/http/http_status_code.h" | 11 #include "net/http/http_status_code.h" |
12 #include "net/url_request/url_fetcher.h" | 12 #include "net/url_request/url_fetcher.h" |
13 #include "net/url_request/url_request_context_getter.h" | 13 #include "net/url_request/url_request_context_getter.h" |
14 #include "third_party/smhasher/src/MurmurHash2.h" | 14 #include "third_party/smhasher/src/MurmurHash2.h" |
15 #include "url/gurl.h" | |
16 | 15 |
17 namespace { | 16 namespace { |
18 | 17 |
19 // The seed to use when taking the murmur2 hash of the icon. | 18 // The seed to use when taking the murmur2 hash of the icon. |
20 const uint64_t kMurmur2HashSeed = 0; | 19 const uint64_t kMurmur2HashSeed = 0; |
21 | 20 |
21 // The default number of milliseconds to wait for the icon download to complete. | |
22 const int kDownloadTimeoutInMilliseconds = 60000; | |
23 | |
22 // Computes Murmur2 hash of |raw_image_data|. | 24 // Computes Murmur2 hash of |raw_image_data|. |
23 std::string ComputeMurmur2Hash(const std::string& raw_image_data) { | 25 std::string ComputeMurmur2Hash(const std::string& raw_image_data) { |
24 // WARNING: We are running in the browser process. |raw_image_data| is the | 26 // WARNING: We are running in the browser process. |raw_image_data| is the |
25 // image's raw, unsanitized bytes from the web. |raw_image_data| may contain | 27 // image's raw, unsanitized bytes from the web. |raw_image_data| may contain |
26 // malicious data. Decoding unsanitized bitmap data to an SkBitmap in the | 28 // malicious data. Decoding unsanitized bitmap data to an SkBitmap in the |
27 // browser process is a security bug. | 29 // browser process is a security bug. |
28 uint64_t hash = MurmurHash64A(&raw_image_data.front(), raw_image_data.size(), | 30 uint64_t hash = MurmurHash64A(&raw_image_data.front(), raw_image_data.size(), |
29 kMurmur2HashSeed); | 31 kMurmur2HashSeed); |
30 return base::Uint64ToString(hash); | 32 return base::Uint64ToString(hash); |
31 } | 33 } |
32 | 34 |
33 } // anonymous namespace | 35 } // anonymous namespace |
34 | 36 |
35 WebApkIconHasher::WebApkIconHasher() {} | 37 WebApkIconHasher::WebApkIconHasher( |
38 net::URLRequestContextGetter* url_request_context_getter, | |
dominickn
2017/03/27 23:27:33
It looks like everywhere this object is used, it's
F
2017/03/29 20:00:49
Thanks for the suggestion! I'll save it for future
| |
39 const GURL& icon_url, | |
40 const Murmur2HashCallback& callback) | |
41 : url_request_context_getter_(url_request_context_getter), | |
42 icon_url_(icon_url), | |
43 callback_(callback), | |
44 weak_ptr_factory_(this) {} | |
36 | 45 |
37 WebApkIconHasher::~WebApkIconHasher() {} | 46 WebApkIconHasher::~WebApkIconHasher() {} |
38 | 47 |
39 void WebApkIconHasher::DownloadAndComputeMurmur2Hash( | 48 void WebApkIconHasher::DownloadAndComputeMurmur2Hash() { |
40 net::URLRequestContextGetter* request_context_getter, | 49 if (!icon_url_.is_valid()) { |
41 const GURL& icon_url, | 50 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
42 const Murmur2HashCallback& callback) { | 51 base::Bind(callback_, "")); |
43 if (icon_url.SchemeIs(url::kDataScheme)) { | 52 return; |
53 } | |
54 | |
55 if (icon_url_.SchemeIs(url::kDataScheme)) { | |
44 std::string mime_type, char_set, data; | 56 std::string mime_type, char_set, data; |
45 std::string hash; | 57 std::string hash; |
46 if (net::DataURL::Parse(icon_url, &mime_type, &char_set, &data) && | 58 if (net::DataURL::Parse(icon_url_, &mime_type, &char_set, &data) && |
47 !data.empty()) { | 59 !data.empty()) { |
48 hash = ComputeMurmur2Hash(data); | 60 hash = ComputeMurmur2Hash(data); |
49 } | 61 } |
50 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 62 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
51 base::Bind(callback, hash)); | 63 base::Bind(callback_, hash)); |
52 return; | 64 return; |
53 } | 65 } |
54 | 66 |
55 callback_ = callback; | 67 download_timeout_timer_.Start( |
56 url_fetcher_ = net::URLFetcher::Create(icon_url, net::URLFetcher::GET, this); | 68 FROM_HERE, |
57 url_fetcher_->SetRequestContext(request_context_getter); | 69 base::TimeDelta::FromMilliseconds(kDownloadTimeoutInMilliseconds), |
70 base::Bind(&WebApkIconHasher::OnDownloadTimedOut, | |
71 weak_ptr_factory_.GetWeakPtr())); | |
72 | |
73 url_fetcher_ = net::URLFetcher::Create(icon_url_, net::URLFetcher::GET, this); | |
74 url_fetcher_->SetRequestContext(url_request_context_getter_); | |
58 url_fetcher_->Start(); | 75 url_fetcher_->Start(); |
59 } | 76 } |
60 | 77 |
61 void WebApkIconHasher::OnURLFetchComplete(const net::URLFetcher* source) { | 78 void WebApkIconHasher::OnURLFetchComplete(const net::URLFetcher* source) { |
79 download_timeout_timer_.Stop(); | |
80 | |
62 if (!source->GetStatus().is_success() || | 81 if (!source->GetStatus().is_success() || |
63 source->GetResponseCode() != net::HTTP_OK) { | 82 source->GetResponseCode() != net::HTTP_OK) { |
64 callback_.Run(""); | 83 callback_.Run(""); |
65 return; | 84 return; |
66 } | 85 } |
67 | 86 |
68 // WARNING: We are running in the browser process. |raw_image_data| is the | 87 // WARNING: We are running in the browser process. |raw_image_data| is the |
69 // image's raw, unsanitized bytes from the web. |raw_image_data| may contain | 88 // image's raw, unsanitized bytes from the web. |raw_image_data| may contain |
70 // malicious data. Decoding unsanitized bitmap data to an SkBitmap in the | 89 // malicious data. Decoding unsanitized bitmap data to an SkBitmap in the |
71 // browser process is a security bug. | 90 // browser process is a security bug. |
72 std::string raw_image_data; | 91 std::string raw_image_data; |
73 source->GetResponseAsString(&raw_image_data); | 92 source->GetResponseAsString(&raw_image_data); |
74 callback_.Run(ComputeMurmur2Hash(raw_image_data)); | 93 callback_.Run(ComputeMurmur2Hash(raw_image_data)); |
75 } | 94 } |
95 | |
96 void WebApkIconHasher::OnDownloadTimedOut() { | |
97 url_fetcher_.reset(); | |
98 | |
99 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | |
100 base::Bind(callback_, "")); | |
101 } | |
OLD | NEW |