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 |