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

Side by Side Diff: chrome/browser/password_manager/password_store_x.cc

Issue 825773003: PasswordStore: Use ScopedVector to express ownership of forms (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Leaks fixed + VABR->vabr Created 5 years, 10 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/password_manager/password_store_x.h" 5 #include "chrome/browser/password_manager/password_store_x.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/prefs/pref_service.h" 13 #include "base/prefs/pref_service.h"
14 #include "base/stl_util.h" 14 #include "base/stl_util.h"
15 #include "chrome/browser/chrome_notification_types.h" 15 #include "chrome/browser/chrome_notification_types.h"
16 #include "components/password_manager/core/browser/password_store_change.h" 16 #include "components/password_manager/core/browser/password_store_change.h"
17 #include "components/password_manager/core/common/password_manager_pref_names.h" 17 #include "components/password_manager/core/common/password_manager_pref_names.h"
18 #include "components/pref_registry/pref_registry_syncable.h" 18 #include "components/pref_registry/pref_registry_syncable.h"
19 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/notification_service.h" 20 #include "content/public/browser/notification_service.h"
21 21
22 using autofill::PasswordForm; 22 using autofill::PasswordForm;
23 using content::BrowserThread; 23 using content::BrowserThread;
24 using password_manager::PasswordStoreChange; 24 using password_manager::PasswordStoreChange;
25 using password_manager::PasswordStoreChangeList; 25 using password_manager::PasswordStoreChangeList;
26 using password_manager::PasswordStoreDefault; 26 using password_manager::PasswordStoreDefault;
27 using std::vector;
28 27
29 namespace { 28 namespace {
30 29
31 bool AddLoginToBackend(const scoped_ptr<PasswordStoreX::NativeBackend>& backend, 30 bool AddLoginToBackend(const scoped_ptr<PasswordStoreX::NativeBackend>& backend,
32 const PasswordForm& form, 31 const PasswordForm& form,
33 PasswordStoreChangeList* changes) { 32 PasswordStoreChangeList* changes) {
34 *changes = backend->AddLogin(form); 33 *changes = backend->AddLogin(form);
35 return (!changes->empty() && 34 return (!changes->empty() &&
36 changes->back().type() == PasswordStoreChange::ADD); 35 changes->back().type() == PasswordStoreChange::ADD);
37 } 36 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 } 122 }
124 123
125 namespace { 124 namespace {
126 struct LoginLessThan { 125 struct LoginLessThan {
127 bool operator()(const PasswordForm* a, const PasswordForm* b) { 126 bool operator()(const PasswordForm* a, const PasswordForm* b) {
128 return a->origin < b->origin; 127 return a->origin < b->origin;
129 } 128 }
130 }; 129 };
131 } // anonymous namespace 130 } // anonymous namespace
132 131
133 void PasswordStoreX::SortLoginsByOrigin(NativeBackend::PasswordFormList* list) { 132 void PasswordStoreX::SortLoginsByOrigin(
133 std::vector<autofill::PasswordForm*>* list) {
134 // In login_database.cc, the query has ORDER BY origin_url. Simulate that. 134 // In login_database.cc, the query has ORDER BY origin_url. Simulate that.
135 std::sort(list->begin(), list->end(), LoginLessThan()); 135 std::sort(list->begin(), list->end(), LoginLessThan());
136 } 136 }
137 137
138 void PasswordStoreX::GetLoginsImpl( 138 void PasswordStoreX::GetLoginsImpl(
139 const autofill::PasswordForm& form, 139 const autofill::PasswordForm& form,
140 AuthorizationPromptPolicy prompt_policy, 140 AuthorizationPromptPolicy prompt_policy,
141 const ConsumerCallbackRunner& callback_runner) { 141 const ConsumerCallbackRunner& callback_runner) {
142 CheckMigration(); 142 CheckMigration();
143 std::vector<autofill::PasswordForm*> matched_forms; 143 ScopedVector<autofill::PasswordForm> matched_forms;
144 if (use_native_backend() && backend_->GetLogins(form, &matched_forms)) { 144 if (use_native_backend() && backend_->GetLogins(form, &matched_forms)) {
145 SortLoginsByOrigin(&matched_forms); 145 SortLoginsByOrigin(&matched_forms.get());
146 // The native backend may succeed and return no data even while locked, if 146 // The native backend may succeed and return no data even while locked, if
147 // the query did not match anything stored. So we continue to allow fallback 147 // the query did not match anything stored. So we continue to allow fallback
148 // until we perform a write operation, or until a read returns actual data. 148 // until we perform a write operation, or until a read returns actual data.
149 if (matched_forms.size() > 0) 149 if (matched_forms.size() > 0)
150 allow_fallback_ = false; 150 allow_fallback_ = false;
151 } else if (allow_default_store()) { 151 } else if (allow_default_store()) {
152 DCHECK(matched_forms.empty()); 152 DCHECK(matched_forms.empty());
153 PasswordStoreDefault::GetLoginsImpl(form, prompt_policy, callback_runner); 153 PasswordStoreDefault::GetLoginsImpl(form, prompt_policy, callback_runner);
154 return; 154 return;
155 } 155 }
156 // The consumer will be left hanging unless we reply. 156 // The consumer will be left hanging unless we reply.
157 callback_runner.Run(matched_forms); 157 callback_runner.Run(&matched_forms);
158 } 158 }
159 159
160 void PasswordStoreX::GetAutofillableLoginsImpl(GetLoginsRequest* request) { 160 void PasswordStoreX::GetAutofillableLoginsImpl(GetLoginsRequest* request) {
161 CheckMigration(); 161 CheckMigration();
162 ScopedVector<autofill::PasswordForm> obtained_forms;
162 if (use_native_backend() && 163 if (use_native_backend() &&
163 backend_->GetAutofillableLogins(request->result())) { 164 backend_->GetAutofillableLogins(&obtained_forms)) {
165 request->result()->swap(obtained_forms.get());
166 obtained_forms.weak_clear(); // TODO(vabr): Change request to have a
vasilii 2015/01/27 20:45:51 Why? request->result() was probably empty. However
vabr (Chromium) 2015/01/28 13:27:36 You are correct. Done.
167 // ScopedVector instead.
164 SortLoginsByOrigin(request->result()); 168 SortLoginsByOrigin(request->result());
165 // See GetLoginsImpl() for why we disallow fallback conditionally here. 169 // See GetLoginsImpl() for why we disallow fallback conditionally here.
166 if (request->result()->size() > 0) 170 if (request->result()->size() > 0)
167 allow_fallback_ = false; 171 allow_fallback_ = false;
168 } else if (allow_default_store()) { 172 } else if (allow_default_store()) {
169 PasswordStoreDefault::GetAutofillableLoginsImpl(request); 173 PasswordStoreDefault::GetAutofillableLoginsImpl(request);
170 return; 174 return;
171 } 175 }
172 // The consumer will be left hanging unless we reply. 176 // The consumer will be left hanging unless we reply.
173 ForwardLoginsResult(request); 177 ForwardLoginsResult(request);
174 } 178 }
175 179
176 void PasswordStoreX::GetBlacklistLoginsImpl(GetLoginsRequest* request) { 180 void PasswordStoreX::GetBlacklistLoginsImpl(GetLoginsRequest* request) {
177 CheckMigration(); 181 CheckMigration();
178 if (use_native_backend() && 182 ScopedVector<autofill::PasswordForm> obtained_forms;
179 backend_->GetBlacklistLogins(request->result())) { 183 if (use_native_backend() && backend_->GetBlacklistLogins(&obtained_forms)) {
184 request->result()->swap(obtained_forms.get());
185 obtained_forms.weak_clear(); // TODO(vabr): Change request to have a
vasilii 2015/01/27 20:45:51 Same as above.
vabr (Chromium) 2015/01/28 13:27:36 Done.
186 // ScopedVector instead.
180 SortLoginsByOrigin(request->result()); 187 SortLoginsByOrigin(request->result());
181 // See GetLoginsImpl() for why we disallow fallback conditionally here. 188 // See GetLoginsImpl() for why we disallow fallback conditionally here.
182 if (request->result()->size() > 0) 189 if (request->result()->size() > 0)
183 allow_fallback_ = false; 190 allow_fallback_ = false;
184 } else if (allow_default_store()) { 191 } else if (allow_default_store()) {
185 PasswordStoreDefault::GetBlacklistLoginsImpl(request); 192 PasswordStoreDefault::GetBlacklistLoginsImpl(request);
186 return; 193 return;
187 } 194 }
188 // The consumer will be left hanging unless we reply. 195 // The consumer will be left hanging unless we reply.
189 ForwardLoginsResult(request); 196 ForwardLoginsResult(request);
190 } 197 }
191 198
192 bool PasswordStoreX::FillAutofillableLogins(vector<PasswordForm*>* forms) { 199 bool PasswordStoreX::FillAutofillableLogins(
200 ScopedVector<autofill::PasswordForm>* forms) {
193 CheckMigration(); 201 CheckMigration();
194 if (use_native_backend() && backend_->GetAutofillableLogins(forms)) { 202 if (use_native_backend() && backend_->GetAutofillableLogins(forms)) {
195 // See GetLoginsImpl() for why we disallow fallback conditionally here. 203 // See GetLoginsImpl() for why we disallow fallback conditionally here.
196 if (forms->size() > 0) 204 if (forms->size() > 0)
197 allow_fallback_ = false; 205 allow_fallback_ = false;
198 return true; 206 return true;
199 } 207 }
200 if (allow_default_store()) 208 if (allow_default_store())
201 return PasswordStoreDefault::FillAutofillableLogins(forms); 209 return PasswordStoreDefault::FillAutofillableLogins(forms);
202 return false; 210 return false;
203 } 211 }
204 212
205 bool PasswordStoreX::FillBlacklistLogins(vector<PasswordForm*>* forms) { 213 bool PasswordStoreX::FillBlacklistLogins(
214 ScopedVector<autofill::PasswordForm>* forms) {
206 CheckMigration(); 215 CheckMigration();
207 if (use_native_backend() && backend_->GetBlacklistLogins(forms)) { 216 if (use_native_backend() && backend_->GetBlacklistLogins(forms)) {
208 // See GetLoginsImpl() for why we disallow fallback conditionally here. 217 // See GetLoginsImpl() for why we disallow fallback conditionally here.
209 if (forms->size() > 0) 218 if (forms->size() > 0)
210 allow_fallback_ = false; 219 allow_fallback_ = false;
211 return true; 220 return true;
212 } 221 }
213 if (allow_default_store()) 222 if (allow_default_store())
214 return PasswordStoreDefault::FillBlacklistLogins(forms); 223 return PasswordStoreDefault::FillBlacklistLogins(forms);
215 return false; 224 return false;
(...skipping 27 matching lines...) Expand all
243 "Falling back on default (unencrypted) store."; 252 "Falling back on default (unencrypted) store.";
244 backend_.reset(NULL); 253 backend_.reset(NULL);
245 // Don't warn again. We'll use the default store because backend_ is NULL. 254 // Don't warn again. We'll use the default store because backend_ is NULL.
246 allow_fallback_ = false; 255 allow_fallback_ = false;
247 } 256 }
248 return !backend_.get(); 257 return !backend_.get();
249 } 258 }
250 259
251 ssize_t PasswordStoreX::MigrateLogins() { 260 ssize_t PasswordStoreX::MigrateLogins() {
252 DCHECK(backend_.get()); 261 DCHECK(backend_.get());
253 vector<PasswordForm*> forms; 262 ScopedVector<autofill::PasswordForm> forms;
254 bool ok = PasswordStoreDefault::FillAutofillableLogins(&forms) && 263 bool ok = PasswordStoreDefault::FillAutofillableLogins(&forms) &&
255 PasswordStoreDefault::FillBlacklistLogins(&forms); 264 PasswordStoreDefault::FillBlacklistLogins(&forms);
256 if (ok) { 265 if (ok) {
257 // We add all the passwords (and blacklist entries) to the native backend 266 // We add all the passwords (and blacklist entries) to the native backend
258 // before attempting to remove any from the login database, to make sure we 267 // before attempting to remove any from the login database, to make sure we
259 // don't somehow end up with some of the passwords in one store and some in 268 // don't somehow end up with some of the passwords in one store and some in
260 // another. We'll always have at least one intact store this way. 269 // another. We'll always have at least one intact store this way.
261 for (size_t i = 0; i < forms.size(); ++i) { 270 for (size_t i = 0; i < forms.size(); ++i) {
262 PasswordStoreChangeList changes; 271 PasswordStoreChangeList changes;
263 if (!AddLoginToBackend(backend_, *forms[i], &changes)) { 272 if (!AddLoginToBackend(backend_, *forms[i], &changes)) {
(...skipping 12 matching lines...) Expand all
276 PasswordStoreDefault::RemoveLoginImpl(*forms[i]); 285 PasswordStoreDefault::RemoveLoginImpl(*forms[i]);
277 } 286 }
278 // Finally, delete the database file itself. We remove the passwords from 287 // Finally, delete the database file itself. We remove the passwords from
279 // it before deleting the file just in case there is some problem deleting 288 // it before deleting the file just in case there is some problem deleting
280 // the file (e.g. directory is not writable, but file is), which would 289 // the file (e.g. directory is not writable, but file is), which would
281 // otherwise cause passwords to re-migrate next (or maybe every) time. 290 // otherwise cause passwords to re-migrate next (or maybe every) time.
282 DeleteAndRecreateDatabaseFile(); 291 DeleteAndRecreateDatabaseFile();
283 } 292 }
284 } 293 }
285 ssize_t result = ok ? forms.size() : -1; 294 ssize_t result = ok ? forms.size() : -1;
286 STLDeleteElements(&forms);
287 return result; 295 return result;
288 } 296 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698