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, |
| 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) {} |
36 | 44 |
37 WebApkIconHasher::~WebApkIconHasher() {} | 45 WebApkIconHasher::~WebApkIconHasher() {} |
38 | 46 |
39 void WebApkIconHasher::DownloadAndComputeMurmur2Hash( | 47 void WebApkIconHasher::DownloadAndComputeMurmur2Hash() { |
40 net::URLRequestContextGetter* request_context_getter, | 48 if (!icon_url_.is_valid()) { |
41 const GURL& icon_url, | 49 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
42 const Murmur2HashCallback& callback) { | 50 base::Bind(callback_, "")); |
43 if (icon_url.SchemeIs(url::kDataScheme)) { | 51 return; |
| 52 } |
| 53 |
| 54 if (icon_url_.SchemeIs(url::kDataScheme)) { |
44 std::string mime_type, char_set, data; | 55 std::string mime_type, char_set, data; |
45 std::string hash; | 56 std::string hash; |
46 if (net::DataURL::Parse(icon_url, &mime_type, &char_set, &data) && | 57 if (net::DataURL::Parse(icon_url_, &mime_type, &char_set, &data) && |
47 !data.empty()) { | 58 !data.empty()) { |
48 hash = ComputeMurmur2Hash(data); | 59 hash = ComputeMurmur2Hash(data); |
49 } | 60 } |
50 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 61 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
51 base::Bind(callback, hash)); | 62 base::Bind(callback_, hash)); |
52 return; | 63 return; |
53 } | 64 } |
54 | 65 |
55 callback_ = callback; | 66 download_timeout_timer_.Start( |
56 url_fetcher_ = net::URLFetcher::Create(icon_url, net::URLFetcher::GET, this); | 67 FROM_HERE, |
57 url_fetcher_->SetRequestContext(request_context_getter); | 68 base::TimeDelta::FromMilliseconds(kDownloadTimeoutInMilliseconds), |
| 69 base::Bind(&WebApkIconHasher::OnDownloadTimedOut, |
| 70 base::Unretained(this))); |
| 71 |
| 72 url_fetcher_ = net::URLFetcher::Create(icon_url_, net::URLFetcher::GET, this); |
| 73 url_fetcher_->SetRequestContext(url_request_context_getter_); |
58 url_fetcher_->Start(); | 74 url_fetcher_->Start(); |
59 } | 75 } |
60 | 76 |
61 void WebApkIconHasher::OnURLFetchComplete(const net::URLFetcher* source) { | 77 void WebApkIconHasher::OnURLFetchComplete(const net::URLFetcher* source) { |
| 78 download_timeout_timer_.Stop(); |
| 79 |
62 if (!source->GetStatus().is_success() || | 80 if (!source->GetStatus().is_success() || |
63 source->GetResponseCode() != net::HTTP_OK) { | 81 source->GetResponseCode() != net::HTTP_OK) { |
64 callback_.Run(""); | 82 callback_.Run(""); |
65 return; | 83 return; |
66 } | 84 } |
67 | 85 |
68 // WARNING: We are running in the browser process. |raw_image_data| is the | 86 // 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 | 87 // 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 | 88 // malicious data. Decoding unsanitized bitmap data to an SkBitmap in the |
71 // browser process is a security bug. | 89 // browser process is a security bug. |
72 std::string raw_image_data; | 90 std::string raw_image_data; |
73 source->GetResponseAsString(&raw_image_data); | 91 source->GetResponseAsString(&raw_image_data); |
74 callback_.Run(ComputeMurmur2Hash(raw_image_data)); | 92 callback_.Run(ComputeMurmur2Hash(raw_image_data)); |
75 } | 93 } |
| 94 |
| 95 void WebApkIconHasher::OnDownloadTimedOut() { |
| 96 url_fetcher_.reset(); |
| 97 |
| 98 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
| 99 base::Bind(callback_, "")); |
| 100 } |
OLD | NEW |