OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "extensions/browser/content_verify_job.h" | 5 #include "extensions/browser/content_verify_job.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
11 #include "base/task_runner_util.h" | 11 #include "base/task_runner_util.h" |
12 #include "base/timer/elapsed_timer.h" | 12 #include "base/timer/elapsed_timer.h" |
13 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
14 #include "crypto/secure_hash.h" | 14 #include "crypto/secure_hash.h" |
15 #include "crypto/sha2.h" | 15 #include "crypto/sha2.h" |
16 #include "extensions/browser/content_hash_reader.h" | 16 #include "extensions/browser/content_hash_reader.h" |
17 | 17 |
18 namespace extensions { | 18 namespace extensions { |
19 | 19 |
20 namespace { | 20 namespace { |
21 | 21 |
22 ContentVerifyJob::TestDelegate* g_test_delegate = NULL; | 22 ContentVerifyJob::TestDelegate* g_test_delegate = NULL; |
23 ContentVerifyJob::TestObserver* g_test_observer = NULL; | 23 ContentVerifyJob::TestObserver* g_test_observer = NULL; |
24 | 24 |
25 class ScopedElapsedTimer { | 25 class ScopedElapsedTimer { |
26 public: | 26 public: |
27 ScopedElapsedTimer(base::TimeDelta* total) : total_(total) { DCHECK(total_); } | 27 explicit ScopedElapsedTimer(base::TimeDelta* total) : total_(total) { |
| 28 DCHECK(total_); |
| 29 } |
28 | 30 |
29 ~ScopedElapsedTimer() { *total_ += timer.Elapsed(); } | 31 ~ScopedElapsedTimer() { *total_ += timer.Elapsed(); } |
30 | 32 |
31 private: | 33 private: |
32 // Some total amount of time we should add our elapsed time to at | 34 // Some total amount of time we should add our elapsed time to at |
33 // destruction. | 35 // destruction. |
34 base::TimeDelta* total_; | 36 base::TimeDelta* total_; |
35 | 37 |
36 // A timer for how long this object has been alive. | 38 // A timer for how long this object has been alive. |
37 base::ElapsedTimer timer; | 39 base::ElapsedTimer timer; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 | 75 |
74 void ContentVerifyJob::BytesRead(int count, const char* data) { | 76 void ContentVerifyJob::BytesRead(int count, const char* data) { |
75 ScopedElapsedTimer timer(&time_spent_); | 77 ScopedElapsedTimer timer(&time_spent_); |
76 DCHECK(thread_checker_.CalledOnValidThread()); | 78 DCHECK(thread_checker_.CalledOnValidThread()); |
77 if (failed_) | 79 if (failed_) |
78 return; | 80 return; |
79 if (g_test_delegate) { | 81 if (g_test_delegate) { |
80 FailureReason reason = | 82 FailureReason reason = |
81 g_test_delegate->BytesRead(hash_reader_->extension_id(), count, data); | 83 g_test_delegate->BytesRead(hash_reader_->extension_id(), count, data); |
82 if (reason != NONE) | 84 if (reason != NONE) |
83 return DispatchFailureCallback(reason); | 85 DispatchFailureCallback(reason); |
| 86 return; |
84 } | 87 } |
85 if (!hashes_ready_) { | 88 if (!hashes_ready_) { |
86 queue_.append(data, count); | 89 queue_.append(data, count); |
87 return; | 90 return; |
88 } | 91 } |
89 DCHECK_GE(count, 0); | 92 DCHECK_GE(count, 0); |
90 int bytes_added = 0; | 93 int bytes_added = 0; |
91 | 94 |
92 while (bytes_added < count) { | 95 while (bytes_added < count) { |
93 if (current_block_ >= hash_reader_->block_count()) | 96 if (current_block_ >= hash_reader_->block_count()) |
94 return DispatchFailureCallback(HASH_MISMATCH); | 97 return DispatchFailureCallback(HASH_MISMATCH); |
95 | 98 |
96 if (!current_hash_.get()) { | 99 if (!current_hash_.get()) { |
97 current_hash_byte_count_ = 0; | 100 current_hash_byte_count_ = 0; |
98 current_hash_.reset( | 101 current_hash_.reset( |
99 crypto::SecureHash::Create(crypto::SecureHash::SHA256)); | 102 crypto::SecureHash::Create(crypto::SecureHash::SHA256)); |
100 } | 103 } |
101 // Compute how many bytes we should hash, and add them to the current hash. | 104 // Compute how many bytes we should hash, and add them to the current hash. |
102 int bytes_to_hash = | 105 int bytes_to_hash = |
103 std::min(hash_reader_->block_size() - current_hash_byte_count_, | 106 std::min(hash_reader_->block_size() - current_hash_byte_count_, |
104 count - bytes_added); | 107 count - bytes_added); |
105 DCHECK(bytes_to_hash > 0); | 108 DCHECK_GT(bytes_to_hash, 0); |
106 current_hash_->Update(data + bytes_added, bytes_to_hash); | 109 current_hash_->Update(data + bytes_added, bytes_to_hash); |
107 bytes_added += bytes_to_hash; | 110 bytes_added += bytes_to_hash; |
108 current_hash_byte_count_ += bytes_to_hash; | 111 current_hash_byte_count_ += bytes_to_hash; |
109 total_bytes_read_ += bytes_to_hash; | 112 total_bytes_read_ += bytes_to_hash; |
110 | 113 |
111 // If we finished reading a block worth of data, finish computing the hash | 114 // If we finished reading a block worth of data, finish computing the hash |
112 // for it and make sure the expected hash matches. | 115 // for it and make sure the expected hash matches. |
113 if (current_hash_byte_count_ == hash_reader_->block_size() && | 116 if (current_hash_byte_count_ == hash_reader_->block_size() && |
114 !FinishBlock()) { | 117 !FinishBlock()) { |
115 DispatchFailureCallback(HASH_MISMATCH); | 118 DispatchFailureCallback(HASH_MISMATCH); |
116 return; | 119 return; |
117 } | 120 } |
118 } | 121 } |
119 } | 122 } |
120 | 123 |
121 void ContentVerifyJob::DoneReading() { | 124 void ContentVerifyJob::DoneReading() { |
122 ScopedElapsedTimer timer(&time_spent_); | 125 ScopedElapsedTimer timer(&time_spent_); |
123 DCHECK(thread_checker_.CalledOnValidThread()); | 126 DCHECK(thread_checker_.CalledOnValidThread()); |
124 if (failed_) | 127 if (failed_) |
125 return; | 128 return; |
126 if (g_test_delegate) { | 129 if (g_test_delegate) { |
127 FailureReason reason = | 130 FailureReason reason = |
128 g_test_delegate->DoneReading(hash_reader_->extension_id()); | 131 g_test_delegate->DoneReading(hash_reader_->extension_id()); |
129 if (reason != NONE) { | 132 if (reason != NONE) |
130 DispatchFailureCallback(reason); | 133 DispatchFailureCallback(reason); |
131 return; | 134 return; |
132 } | |
133 } | 135 } |
134 done_reading_ = true; | 136 done_reading_ = true; |
135 if (hashes_ready_) { | 137 if (hashes_ready_) { |
136 if (!FinishBlock()) | 138 if (!FinishBlock()) |
137 DispatchFailureCallback(HASH_MISMATCH); | 139 DispatchFailureCallback(HASH_MISMATCH); |
138 else if (g_test_observer) | 140 else if (g_test_observer) |
139 g_test_observer->JobFinished(hash_reader_->extension_id(), | 141 g_test_observer->JobFinished(hash_reader_->extension_id(), |
140 hash_reader_->relative_path(), failed_); | 142 hash_reader_->relative_path(), failed_); |
141 } | 143 } |
142 } | 144 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 } | 176 } |
175 | 177 |
176 hashes_ready_ = true; | 178 hashes_ready_ = true; |
177 if (!queue_.empty()) { | 179 if (!queue_.empty()) { |
178 std::string tmp; | 180 std::string tmp; |
179 queue_.swap(tmp); | 181 queue_.swap(tmp); |
180 BytesRead(tmp.size(), string_as_array(&tmp)); | 182 BytesRead(tmp.size(), string_as_array(&tmp)); |
181 } | 183 } |
182 if (done_reading_) { | 184 if (done_reading_) { |
183 ScopedElapsedTimer timer(&time_spent_); | 185 ScopedElapsedTimer timer(&time_spent_); |
184 if (!FinishBlock()) | 186 if (!FinishBlock()) { |
185 DispatchFailureCallback(HASH_MISMATCH); | 187 DispatchFailureCallback(HASH_MISMATCH); |
186 else if (g_test_observer) { | 188 } else if (g_test_observer) { |
187 g_test_observer->JobFinished(hash_reader_->extension_id(), | 189 g_test_observer->JobFinished(hash_reader_->extension_id(), |
188 hash_reader_->relative_path(), failed_); | 190 hash_reader_->relative_path(), failed_); |
189 } | 191 } |
190 } | 192 } |
191 } | 193 } |
192 | 194 |
193 // static | 195 // static |
194 void ContentVerifyJob::SetDelegateForTests(TestDelegate* delegate) { | 196 void ContentVerifyJob::SetDelegateForTests(TestDelegate* delegate) { |
195 g_test_delegate = delegate; | 197 g_test_delegate = delegate; |
196 } | 198 } |
(...skipping 12 matching lines...) Expand all Loading... |
209 << " reason:" << reason; | 211 << " reason:" << reason; |
210 failure_callback_.Run(reason); | 212 failure_callback_.Run(reason); |
211 failure_callback_.Reset(); | 213 failure_callback_.Reset(); |
212 } | 214 } |
213 if (g_test_observer) | 215 if (g_test_observer) |
214 g_test_observer->JobFinished( | 216 g_test_observer->JobFinished( |
215 hash_reader_->extension_id(), hash_reader_->relative_path(), failed_); | 217 hash_reader_->extension_id(), hash_reader_->relative_path(), failed_); |
216 } | 218 } |
217 | 219 |
218 } // namespace extensions | 220 } // namespace extensions |
OLD | NEW |