Chromium Code Reviews| 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 |