Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: components/safe_browsing/password_protection/password_protection_service.cc

Issue 2773483003: Create PasswordProtectionRequest to handle password pings (Closed)
Patch Set: fix SB cookie test Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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 "components/safe_browsing/password_protection/password_protection_servi ce.h" 5 #include "components/safe_browsing/password_protection/password_protection_servi ce.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
10 #include "base/metrics/histogram_macros.h" 10 #include "base/metrics/histogram_macros.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_split.h" 12 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "components/safe_browsing/password_protection/password_protection_reque st.h"
14 #include "components/safe_browsing_db/database_manager.h" 15 #include "components/safe_browsing_db/database_manager.h"
15 #include "components/safe_browsing_db/v4_protocol_manager_util.h" 16 #include "components/safe_browsing_db/v4_protocol_manager_util.h"
16 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/browser_thread.h"
18 #include "google_apis/google_api_keys.h"
19 #include "net/base/escape.h"
17 20
18 using content::BrowserThread; 21 using content::BrowserThread;
19 22
20 namespace safe_browsing { 23 namespace safe_browsing {
21 24
22 namespace { 25 namespace {
23 26
24 // Keys for storing password protection verdict into a DictionaryValue. 27 // Keys for storing password protection verdict into a DictionaryValue.
25 static const char kCacheCreationTime[] = "cache_creation_time"; 28 const char kCacheCreationTime[] = "cache_creation_time";
26 static const char kVerdictProto[] = "verdict_proto"; 29 const char kVerdictProto[] = "verdict_proto";
30 // Request times out in 10 ms.
Nathan Parker 2017/03/23 20:45:51 nit: The comment here doesn't add anything.
Jialiu Lin 2017/03/23 22:43:02 Removed.
31 const int kRequestTimeoutMS = 10;
Nathan Parker 2017/03/23 20:45:50 Should be 10000 ms. Or you could call it seconds
Jialiu Lin 2017/03/23 22:43:01 Done.
32 const char kPasswordProtectionRequestUrl[] =
33 "https://sb-ssl.google.com/safebrowsing/clientreport/login";
27 34
28 // Helper function to determine if the given origin matches content settings 35 // Helper function to determine if the given origin matches content settings
29 // map's patterns. 36 // map's patterns.
30 bool OriginMatchPrimaryPattern( 37 bool OriginMatchPrimaryPattern(
31 const GURL& origin, 38 const GURL& origin,
32 const ContentSettingsPattern& primary_pattern, 39 const ContentSettingsPattern& primary_pattern,
33 const ContentSettingsPattern& secondary_pattern_unused) { 40 const ContentSettingsPattern& secondary_pattern_unused) {
34 return ContentSettingsPattern::FromURLNoWildcard(origin) == primary_pattern; 41 return ContentSettingsPattern::FromURLNoWildcard(origin) == primary_pattern;
35 } 42 }
36 43
(...skipping 11 matching lines...) Expand all
48 GURL GetHostNameWithHTTPScheme(const GURL& url) { 55 GURL GetHostNameWithHTTPScheme(const GURL& url) {
49 DCHECK(url.SchemeIsHTTPOrHTTPS()); 56 DCHECK(url.SchemeIsHTTPOrHTTPS());
50 std::string result(url::kHttpScheme); 57 std::string result(url::kHttpScheme);
51 result.append(url::kStandardSchemeSeparator).append(url.HostNoBrackets()); 58 result.append(url::kStandardSchemeSeparator).append(url.HostNoBrackets());
52 return GURL(result); 59 return GURL(result);
53 } 60 }
54 61
55 } // namespace 62 } // namespace
56 63
57 PasswordProtectionService::PasswordProtectionService( 64 PasswordProtectionService::PasswordProtectionService(
58 const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager) 65 const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager,
59 : database_manager_(database_manager), weak_factory_(this) { 66 scoped_refptr<net::URLRequestContextGetter> request_context_getter)
67 : request_context_getter_(request_context_getter),
68 database_manager_(database_manager),
69 weak_factory_(this) {
60 DCHECK_CURRENTLY_ON(BrowserThread::UI); 70 DCHECK_CURRENTLY_ON(BrowserThread::UI);
61 } 71 }
62 72
63 PasswordProtectionService::~PasswordProtectionService() { 73 PasswordProtectionService::~PasswordProtectionService() {
74 CancelPendingRequests();
64 weak_factory_.InvalidateWeakPtrs(); 75 weak_factory_.InvalidateWeakPtrs();
65 } 76 }
66 77
67 void PasswordProtectionService::RecordPasswordReuse(const GURL& url) { 78 void PasswordProtectionService::RecordPasswordReuse(const GURL& url) {
68 DCHECK_CURRENTLY_ON(BrowserThread::UI); 79 DCHECK_CURRENTLY_ON(BrowserThread::UI);
69 DCHECK(database_manager_); 80 DCHECK(database_manager_);
70 if (!url.is_valid()) 81 if (!url.is_valid())
71 return; 82 return;
72 83
73 BrowserThread::PostTaskAndReplyWithResult( 84 BrowserThread::PostTask(
74 BrowserThread::IO, FROM_HERE, 85 BrowserThread::IO, FROM_HERE,
75 base::Bind(&SafeBrowsingDatabaseManager::MatchCsdWhitelistUrl, 86 base::Bind(
76 database_manager_, url), 87 &PasswordProtectionService::CheckCsdWhitelistOnIOThread, GetWeakPtr(),
77 base::Bind(&PasswordProtectionService::OnMatchCsdWhiteListResult, 88 url,
78 GetWeakPtr())); 89 base::Bind(&PasswordProtectionService::OnMatchCsdWhiteListResult,
90 GetWeakPtr())));
91 }
92
93 void PasswordProtectionService::CheckCsdWhitelistOnIOThread(
94 const GURL& url,
95 const CheckCsdWhitelistCallback& callback) {
96 DCHECK_CURRENTLY_ON(BrowserThread::IO);
97 DCHECK(database_manager_);
98 bool check_result = database_manager_->MatchCsdWhitelistUrl(url);
99 DCHECK(callback);
100 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
101 base::Bind(callback, check_result));
79 } 102 }
80 103
81 LoginReputationClientResponse::VerdictType 104 LoginReputationClientResponse::VerdictType
82 PasswordProtectionService::GetCachedVerdict( 105 PasswordProtectionService::GetCachedVerdict(
83 const HostContentSettingsMap* settings, 106 const HostContentSettingsMap* settings,
84 const GURL& url) { 107 const GURL& url,
85 // TODO(jialiul): Add UMA metrics to track if verdict is available, not 108 LoginReputationClientResponse* out_response) {
86 // available, or expired.
87 DCHECK(settings); 109 DCHECK(settings);
88 if (!url.is_valid()) { 110 if (!url.is_valid()) {
89 return LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED; 111 return LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED;
90 } 112 }
91 113
92 GURL hostname = GetHostNameWithHTTPScheme(url); 114 GURL hostname = GetHostNameWithHTTPScheme(url);
93 std::unique_ptr<base::DictionaryValue> verdict_dictionary = 115 std::unique_ptr<base::DictionaryValue> verdict_dictionary =
94 base::DictionaryValue::From(settings->GetWebsiteSetting( 116 base::DictionaryValue::From(settings->GetWebsiteSetting(
95 hostname, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, 117 hostname, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION,
96 std::string(), nullptr)); 118 std::string(), nullptr));
97 // Return early if there is no verdict cached for this origin. 119 // Return early if there is no verdict cached for this origin.
98 if (!verdict_dictionary.get() || verdict_dictionary->empty()) { 120 if (!verdict_dictionary.get() || verdict_dictionary->empty())
99 return LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED; 121 return LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED;
100 }
101 122
102 std::vector<std::string> paths; 123 std::vector<std::string> paths;
103 GeneratePathVariantsWithoutQuery(url, &paths); 124 GeneratePathVariantsWithoutQuery(url, &paths);
104 size_t max_path_depth = 0U; 125 size_t max_path_depth = 0U;
105 LoginReputationClientResponse::VerdictType most_matching_verdict = 126 LoginReputationClientResponse::VerdictType most_matching_verdict =
106 LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED; 127 LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED;
107 // For all the verdicts of the same origin, we key them by |cache_expression|. 128 // For all the verdicts of the same origin, we key them by |cache_expression|.
108 // Its corresponding value is a DictionaryValue contains its creation time and 129 // Its corresponding value is a DictionaryValue contains its creation time and
109 // the serialized verdict proto. 130 // the serialized verdict proto.
110 for (base::DictionaryValue::Iterator it(*verdict_dictionary.get()); 131 for (base::DictionaryValue::Iterator it(*verdict_dictionary.get());
111 !it.IsAtEnd(); it.Advance()) { 132 !it.IsAtEnd(); it.Advance()) {
112 base::DictionaryValue* verdict_entry = nullptr; 133 base::DictionaryValue* verdict_entry = nullptr;
113 CHECK(verdict_dictionary->GetDictionaryWithoutPathExpansion( 134 CHECK(verdict_dictionary->GetDictionaryWithoutPathExpansion(
114 it.key() /* cache_expression */, &verdict_entry)); 135 it.key() /* cache_expression */, &verdict_entry));
115 int verdict_received_time; 136 int verdict_received_time;
116 LoginReputationClientResponse verdict; 137 LoginReputationClientResponse verdict;
117 CHECK(ParseVerdictEntry(verdict_entry, &verdict_received_time, &verdict)); 138 CHECK(ParseVerdictEntry(verdict_entry, &verdict_received_time, &verdict));
118 // Since password protection content settings are keyed by origin, we only 139 // Since password protection content settings are keyed by origin, we only
119 // need to compare the path part of the cache_expression and the given url. 140 // need to compare the path part of the cache_expression and the given url.
120 std::string cache_expression_path = 141 std::string cache_expression_path =
121 GetCacheExpressionPath(verdict.cache_expression()); 142 GetCacheExpressionPath(verdict.cache_expression());
122 143
123 if (verdict.cache_expression_exact_match()) { 144 if (verdict.cache_expression_exact_match()) {
124 if (PathMatchCacheExpressionExactly(paths, cache_expression_path)) { 145 if (PathMatchCacheExpressionExactly(paths, cache_expression_path)) {
125 return IsCacheExpired(verdict_received_time, 146 if (!IsCacheExpired(verdict_received_time,
126 verdict.cache_duration_sec()) 147 verdict.cache_duration_sec())) {
127 ? LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED 148 out_response->CopyFrom(verdict);
128 : verdict.verdict_type(); 149 return verdict.verdict_type();
150 } else { // verdict expired
151 return LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED;
152 }
129 } 153 }
130 } else { 154 } else {
131 // If it doesn't require exact match, we need to fine the most specific 155 // If it doesn't require exact match, we need to fine the most specific
Nathan Parker 2017/03/23 20:45:51 nit: find
Jialiu Lin 2017/03/23 22:43:01 Done.
132 // match. 156 // match.
133 size_t path_depth = GetPathDepth(cache_expression_path); 157 size_t path_depth = GetPathDepth(cache_expression_path);
134 if (path_depth > max_path_depth && 158 if (path_depth > max_path_depth &&
135 PathVariantsMatchCacheExpression(paths, cache_expression_path) && 159 PathVariantsMatchCacheExpression(paths, cache_expression_path) &&
136 !IsCacheExpired(verdict_received_time, 160 !IsCacheExpired(verdict_received_time,
137 verdict.cache_duration_sec())) { 161 verdict.cache_duration_sec())) {
138 max_path_depth = path_depth; 162 max_path_depth = path_depth;
139 most_matching_verdict = verdict.verdict_type(); 163 most_matching_verdict = verdict.verdict_type();
164 out_response->CopyFrom(verdict);
140 } 165 }
141 } 166 }
142 } 167 }
143 return most_matching_verdict; 168 return most_matching_verdict;
144 } 169 }
145 170
146 void PasswordProtectionService::CacheVerdict( 171 void PasswordProtectionService::CacheVerdict(
147 const GURL& url, 172 const GURL& url,
148 LoginReputationClientResponse* verdict, 173 LoginReputationClientResponse* verdict,
149 const base::Time& receive_time, 174 const base::Time& receive_time,
150 HostContentSettingsMap* settings) { 175 HostContentSettingsMap* settings) {
151 DCHECK(verdict); 176 DCHECK(verdict);
152 177
153 GURL hostname = GetHostNameWithHTTPScheme(url); 178 GURL hostname = GetHostNameWithHTTPScheme(url);
154 std::unique_ptr<base::DictionaryValue> verdict_dictionary = 179 std::unique_ptr<base::DictionaryValue> verdict_dictionary =
155 base::DictionaryValue::From(settings->GetWebsiteSetting( 180 base::DictionaryValue::From(settings->GetWebsiteSetting(
156 hostname, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, 181 hostname, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION,
157 std::string(), nullptr)); 182 std::string(), nullptr));
158 183
159 if (!verdict_dictionary.get()) 184 if (!verdict_dictionary.get())
160 verdict_dictionary = base::MakeUnique<base::DictionaryValue>(); 185 verdict_dictionary = base::MakeUnique<base::DictionaryValue>();
161 186
162 std::unique_ptr<base::DictionaryValue> verdict_entry = 187 std::unique_ptr<base::DictionaryValue> verdict_entry =
163 CreateDictionaryFromVerdict(verdict, receive_time); 188 CreateDictionaryFromVerdict(verdict, receive_time);
189
190 // Increases stored verdict count if we haven't seen this its cache expression
191 // before.
192 if (!verdict_dictionary->HasKey(verdict->cache_expression()))
193 stored_verdict_counts_[settings] = GetStoredVerdictCount() + 1U;
164 // If same cache_expression is already in this verdict_dictionary, we simply 194 // If same cache_expression is already in this verdict_dictionary, we simply
165 // override it. 195 // override it.
166 verdict_dictionary->SetWithoutPathExpansion(verdict->cache_expression(), 196 verdict_dictionary->SetWithoutPathExpansion(verdict->cache_expression(),
167 std::move(verdict_entry)); 197 std::move(verdict_entry));
168 settings->SetWebsiteSettingDefaultScope( 198 settings->SetWebsiteSettingDefaultScope(
169 hostname, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, 199 hostname, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION,
170 std::string(), std::move(verdict_dictionary)); 200 std::string(), std::move(verdict_dictionary));
171 } 201 }
172 202
203 void PasswordProtectionService::StartRequest(
204 const GURL& main_frame_url,
205 LoginReputationClientRequest::TriggerType type,
206 bool is_extended_reporting,
207 bool is_incognito) {
208 DCHECK_CURRENTLY_ON(BrowserThread::UI);
209 std::unique_ptr<PasswordProtectionRequest> request =
210 base::MakeUnique<PasswordProtectionRequest>(
211 main_frame_url, type, is_extended_reporting, is_incognito,
212 GetWeakPtr(), GetRequestTimeoutInMS());
213 DCHECK(request);
214 requests_[request.get()] = std::move(request);
215 }
216
217 void PasswordProtectionService::RequestFinished(
218 PasswordProtectionRequest* request,
219 std::unique_ptr<LoginReputationClientResponse> response) {
220 DCHECK_CURRENTLY_ON(BrowserThread::UI);
221
222 DCHECK(request);
223 // TODO(jialiul): We don't cache verdict for incognito mode for now.
224 // Later we may consider temporarily caching verdict.
225 if (!request->is_incognito()) {
226 CacheVerdict(request->main_frame_url(), response.get(), base::Time::Now(),
227 GetSettingMapForActiveProfile());
228 }
229 // Finished processing this request. Remove it from pending list.
230 auto it = requests_.find(request);
231 DCHECK(it != requests_.end());
232 requests_.erase(it);
233 }
234
235 void PasswordProtectionService::CancelPendingRequests() {
236 DCHECK_CURRENTLY_ON(BrowserThread::UI);
237 for (auto it = requests_.begin(); it != requests_.end();) {
238 // We need to advance the iterator before we cancel because canceling
239 // the request will invalidate it when RequestFinished is called.
240 PasswordProtectionRequest* request = it->first;
241 DCHECK(request);
242 request->Cancel(false);
243 }
244 DCHECK(requests_.empty());
245 }
246
247 GURL PasswordProtectionService::GetPasswordProtectionRequestUrl() {
248 GURL url(kPasswordProtectionRequestUrl);
249 std::string api_key = google_apis::GetAPIKey();
250 DCHECK(!api_key.empty());
251 return url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true));
252 }
253
254 size_t PasswordProtectionService::GetStoredVerdictCount() {
255 HostContentSettingsMap* content_setting_map = GetSettingMapForActiveProfile();
256 DCHECK(content_setting_map);
257 auto it = stored_verdict_counts_.find(content_setting_map);
258 // If we have already computed this, return its value.
259 if (it != stored_verdict_counts_.end())
260 return it->second;
261
262 ContentSettingsForOneType password_protection_settings;
263 content_setting_map->GetSettingsForOneType(
264 CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(),
265 &password_protection_settings);
266 if (password_protection_settings.empty())
267 return 0U;
268 stored_verdict_counts_[content_setting_map] = 0U;
Nathan Parker 2017/03/23 20:45:51 I think this should go above the if(), so next tim
Jialiu Lin 2017/03/23 22:43:01 Done.
269 for (const ContentSettingPatternSource& source :
270 password_protection_settings) {
271 std::unique_ptr<base::DictionaryValue> verdict_dictionary =
272 base::DictionaryValue::From(content_setting_map->GetWebsiteSetting(
Nathan Parker 2017/03/23 20:45:50 Depending on how much work this function does, thi
Jialiu Lin 2017/03/23 22:43:02 Acknowledged. Unfortunately there is no function e
273 GURL(source.primary_pattern.ToString()), GURL(),
274 CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(), nullptr));
275 stored_verdict_counts_[content_setting_map] += verdict_dictionary->size();
276 }
277 return stored_verdict_counts_[content_setting_map];
278 }
279
280 int PasswordProtectionService::GetRequestTimeoutInMS() {
281 return kRequestTimeoutMS;
282 }
283
173 void PasswordProtectionService::OnMatchCsdWhiteListResult( 284 void PasswordProtectionService::OnMatchCsdWhiteListResult(
174 bool match_whitelist) { 285 bool match_whitelist) {
175 DCHECK_CURRENTLY_ON(BrowserThread::UI);
176 UMA_HISTOGRAM_BOOLEAN( 286 UMA_HISTOGRAM_BOOLEAN(
177 "PasswordManager.PasswordReuse.MainFrameMatchCsdWhitelist", 287 "PasswordManager.PasswordReuse.MainFrameMatchCsdWhitelist",
178 match_whitelist); 288 match_whitelist);
179 } 289 }
180 290
181 HostContentSettingsMap* 291 HostContentSettingsMap*
182 PasswordProtectionService::GetSettingMapForActiveProfile() { 292 PasswordProtectionService::GetSettingMapForActiveProfile() {
183 // TODO(jialiul): Make this a pure virtual function when we have a derived 293 // TODO(jialiul): Make this a pure virtual function when we have a derived
184 // class ready in chrome/browser/safe_browsing directory. 294 // class ready in chrome/browser/safe_browsing directory.
185 return nullptr; 295 return nullptr;
(...skipping 16 matching lines...) Expand all
202 } 312 }
203 313
204 void PasswordProtectionService::RemoveContentSettingsOnURLsDeleted( 314 void PasswordProtectionService::RemoveContentSettingsOnURLsDeleted(
205 bool all_history, 315 bool all_history,
206 const history::URLRows& deleted_rows, 316 const history::URLRows& deleted_rows,
207 HostContentSettingsMap* setting_map) { 317 HostContentSettingsMap* setting_map) {
208 DCHECK_CURRENTLY_ON(BrowserThread::UI); 318 DCHECK_CURRENTLY_ON(BrowserThread::UI);
209 if (all_history) { 319 if (all_history) {
210 setting_map->ClearSettingsForOneType( 320 setting_map->ClearSettingsForOneType(
211 CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION); 321 CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION);
322 stored_verdict_counts_[setting_map] = 0U;
212 return; 323 return;
213 } 324 }
214 325
215 // For now, if a URL is deleted from history, we simply remove all the 326 // For now, if a URL is deleted from history, we simply remove all the
216 // cached verdicts of the same origin. This is a pretty aggressive deletion. 327 // cached verdicts of the same origin. This is a pretty aggressive deletion.
217 // We might revisit this logic later to decide if we want to only delete the 328 // We might revisit this logic later to decide if we want to only delete the
218 // cached verdict whose cache expression matches this URL. 329 // cached verdict whose cache expression matches this URL.
219 for (const history::URLRow& row : deleted_rows) { 330 for (const history::URLRow& row : deleted_rows) {
331 GURL url_key = GetHostNameWithHTTPScheme(row.url());
332 std::unique_ptr<base::DictionaryValue> verdict_dictionary =
333 base::DictionaryValue::From(setting_map->GetWebsiteSetting(
334 url_key, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION,
335 std::string(), nullptr));
336 size_t verdict_cnt = verdict_dictionary->size();
337 stored_verdict_counts_[setting_map] = GetStoredVerdictCount() - verdict_cnt;
Nathan Parker 2017/03/23 20:45:51 Is it possible for the setting_map here to differ
Jialiu Lin 2017/03/23 22:43:02 setting_map is per profile. My next CL will make s
220 setting_map->ClearSettingsForOneTypeWithPredicate( 338 setting_map->ClearSettingsForOneTypeWithPredicate(
221 CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, 339 CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION,
222 base::Bind(&OriginMatchPrimaryPattern, row.url().GetOrigin())); 340 base::Bind(&OriginMatchPrimaryPattern, url_key));
341 DCHECK_LE(0U, stored_verdict_counts_[setting_map]);
Nathan Parker 2017/03/23 20:45:51 This is guaranteed to never fire, since they're un
Jialiu Lin 2017/03/23 22:43:02 Actually I don't need this DCHECK, since size_t ty
Nathan Parker 2017/03/24 00:41:50 ok, but you could DCHECK(GetStoredVerdictCount() >
223 } 342 }
224 } 343 }
225 344
226 // static 345 // static
227 bool PasswordProtectionService::ParseVerdictEntry( 346 bool PasswordProtectionService::ParseVerdictEntry(
228 base::DictionaryValue* verdict_entry, 347 base::DictionaryValue* verdict_entry,
229 int* out_verdict_received_time, 348 int* out_verdict_received_time,
230 LoginReputationClientResponse* out_verdict) { 349 LoginReputationClientResponse* out_verdict) {
231 base::Value* binary_value = nullptr; 350 base::Value* binary_value = nullptr;
232 bool result = verdict_entry && out_verdict && 351 bool result = verdict_entry && out_verdict &&
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 const std::vector<char> verdict_blob(serialized_proto.begin(), 437 const std::vector<char> verdict_blob(serialized_proto.begin(),
319 serialized_proto.end()); 438 serialized_proto.end());
320 std::unique_ptr<base::Value> binary_value = 439 std::unique_ptr<base::Value> binary_value =
321 base::MakeUnique<base::Value>(verdict_blob); 440 base::MakeUnique<base::Value>(verdict_blob);
322 DCHECK_EQ(base::Value::Type::BINARY, binary_value->type()); 441 DCHECK_EQ(base::Value::Type::BINARY, binary_value->type());
323 result->Set(kVerdictProto, std::move(binary_value)); 442 result->Set(kVerdictProto, std::move(binary_value));
324 return result; 443 return result;
325 } 444 }
326 445
327 } // namespace safe_browsing 446 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698