| 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" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 // 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 |
| 28 // malicious data. Decoding unsanitized bitmap data to an SkBitmap in the | 28 // malicious data. Decoding unsanitized bitmap data to an SkBitmap in the |
| 29 // browser process is a security bug. | 29 // browser process is a security bug. |
| 30 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(), |
| 31 kMurmur2HashSeed); | 31 kMurmur2HashSeed); |
| 32 return base::Uint64ToString(hash); | 32 return base::Uint64ToString(hash); |
| 33 } | 33 } |
| 34 | 34 |
| 35 } // anonymous namespace | 35 } // anonymous namespace |
| 36 | 36 |
| 37 // static |
| 38 void WebApkIconHasher::DownloadAndComputeMurmur2Hash( |
| 39 net::URLRequestContextGetter* request_context_getter, |
| 40 const GURL& icon_url, |
| 41 const Murmur2HashCallback& callback) { |
| 42 if (!icon_url.is_valid()) { |
| 43 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
| 44 base::Bind(callback, "")); |
| 45 return; |
| 46 } |
| 47 |
| 48 if (icon_url.SchemeIs(url::kDataScheme)) { |
| 49 std::string mime_type, char_set, data; |
| 50 std::string hash; |
| 51 if (net::DataURL::Parse(icon_url, &mime_type, &char_set, &data) && |
| 52 !data.empty()) { |
| 53 hash = ComputeMurmur2Hash(data); |
| 54 } |
| 55 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
| 56 base::Bind(callback, hash)); |
| 57 return; |
| 58 } |
| 59 |
| 60 // The icon hasher will delete itself when it is done. |
| 61 new WebApkIconHasher(request_context_getter, icon_url, callback); |
| 62 } |
| 63 |
| 37 WebApkIconHasher::WebApkIconHasher( | 64 WebApkIconHasher::WebApkIconHasher( |
| 38 net::URLRequestContextGetter* url_request_context_getter, | 65 net::URLRequestContextGetter* url_request_context_getter, |
| 39 const GURL& icon_url, | 66 const GURL& icon_url, |
| 40 const Murmur2HashCallback& callback) | 67 const Murmur2HashCallback& callback) |
| 41 : url_request_context_getter_(url_request_context_getter), | 68 : callback_(callback) { |
| 42 icon_url_(icon_url), | |
| 43 callback_(callback) {} | |
| 44 | |
| 45 WebApkIconHasher::~WebApkIconHasher() {} | |
| 46 | |
| 47 void WebApkIconHasher::DownloadAndComputeMurmur2Hash() { | |
| 48 if (!icon_url_.is_valid()) { | |
| 49 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | |
| 50 base::Bind(callback_, "")); | |
| 51 return; | |
| 52 } | |
| 53 | |
| 54 if (icon_url_.SchemeIs(url::kDataScheme)) { | |
| 55 std::string mime_type, char_set, data; | |
| 56 std::string hash; | |
| 57 if (net::DataURL::Parse(icon_url_, &mime_type, &char_set, &data) && | |
| 58 !data.empty()) { | |
| 59 hash = ComputeMurmur2Hash(data); | |
| 60 } | |
| 61 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | |
| 62 base::Bind(callback_, hash)); | |
| 63 return; | |
| 64 } | |
| 65 | |
| 66 download_timeout_timer_.Start( | 69 download_timeout_timer_.Start( |
| 67 FROM_HERE, | 70 FROM_HERE, |
| 68 base::TimeDelta::FromMilliseconds(kDownloadTimeoutInMilliseconds), | 71 base::TimeDelta::FromMilliseconds(kDownloadTimeoutInMilliseconds), |
| 69 base::Bind(&WebApkIconHasher::OnDownloadTimedOut, | 72 base::Bind(&WebApkIconHasher::OnDownloadTimedOut, |
| 70 base::Unretained(this))); | 73 base::Unretained(this))); |
| 71 | 74 |
| 72 url_fetcher_ = net::URLFetcher::Create(icon_url_, net::URLFetcher::GET, this); | 75 url_fetcher_ = net::URLFetcher::Create(icon_url, net::URLFetcher::GET, this); |
| 73 url_fetcher_->SetRequestContext(url_request_context_getter_); | 76 url_fetcher_->SetRequestContext(url_request_context_getter); |
| 74 url_fetcher_->Start(); | 77 url_fetcher_->Start(); |
| 75 } | 78 } |
| 76 | 79 |
| 80 WebApkIconHasher::~WebApkIconHasher() {} |
| 81 |
| 77 void WebApkIconHasher::OnURLFetchComplete(const net::URLFetcher* source) { | 82 void WebApkIconHasher::OnURLFetchComplete(const net::URLFetcher* source) { |
| 78 download_timeout_timer_.Stop(); | 83 download_timeout_timer_.Stop(); |
| 79 | 84 |
| 80 if (!source->GetStatus().is_success() || | 85 if (!source->GetStatus().is_success() || |
| 81 source->GetResponseCode() != net::HTTP_OK) { | 86 source->GetResponseCode() != net::HTTP_OK) { |
| 82 callback_.Run(""); | 87 RunCallback(""); |
| 83 return; | 88 return; |
| 84 } | 89 } |
| 85 | 90 |
| 86 // WARNING: We are running in the browser process. |raw_image_data| is the | 91 // WARNING: We are running in the browser process. |raw_image_data| is the |
| 87 // image's raw, unsanitized bytes from the web. |raw_image_data| may contain | 92 // image's raw, unsanitized bytes from the web. |raw_image_data| may contain |
| 88 // malicious data. Decoding unsanitized bitmap data to an SkBitmap in the | 93 // malicious data. Decoding unsanitized bitmap data to an SkBitmap in the |
| 89 // browser process is a security bug. | 94 // browser process is a security bug. |
| 90 std::string raw_image_data; | 95 std::string raw_image_data; |
| 91 source->GetResponseAsString(&raw_image_data); | 96 source->GetResponseAsString(&raw_image_data); |
| 92 callback_.Run(ComputeMurmur2Hash(raw_image_data)); | 97 RunCallback(ComputeMurmur2Hash(raw_image_data)); |
| 93 } | 98 } |
| 94 | 99 |
| 95 void WebApkIconHasher::OnDownloadTimedOut() { | 100 void WebApkIconHasher::OnDownloadTimedOut() { |
| 96 url_fetcher_.reset(); | 101 url_fetcher_.reset(); |
| 97 | 102 |
| 98 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 103 RunCallback(""); |
| 99 base::Bind(callback_, "")); | |
| 100 } | 104 } |
| 105 |
| 106 void WebApkIconHasher::RunCallback(const std::string& icon_murmur2_hash) { |
| 107 callback_.Run(icon_murmur2_hash); |
| 108 delete this; |
| 109 } |
| OLD | NEW |