 Chromium Code Reviews
 Chromium Code Reviews Issue 825773003:
  PasswordStore: Use ScopedVector to express ownership of forms  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 825773003:
  PasswordStore: Use ScopedVector to express ownership of forms  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| OLD | NEW | 
|---|---|
| 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_mac.h" | 5 #include "chrome/browser/password_manager/password_store_mac.h" | 
| 6 #include "chrome/browser/password_manager/password_store_mac_internal.h" | 6 #include "chrome/browser/password_manager/password_store_mac_internal.h" | 
| 7 | 7 | 
| 8 #include <CoreServices/CoreServices.h> | 8 #include <CoreServices/CoreServices.h> | 
| 9 #include <set> | 9 #include <set> | 
| 10 #include <string> | 10 #include <string> | 
| 11 #include <utility> | 11 #include <utility> | 
| 12 #include <vector> | 12 #include <vector> | 
| 13 | 13 | 
| 14 #include "base/callback.h" | 14 #include "base/callback.h" | 
| 15 #include "base/logging.h" | 15 #include "base/logging.h" | 
| 16 #include "base/mac/foundation_util.h" | 16 #include "base/mac/foundation_util.h" | 
| 17 #include "base/mac/mac_logging.h" | 17 #include "base/mac/mac_logging.h" | 
| 18 #include "base/memory/scoped_vector.h" | |
| 19 #include "base/message_loop/message_loop.h" | 18 #include "base/message_loop/message_loop.h" | 
| 20 #include "base/stl_util.h" | 19 #include "base/stl_util.h" | 
| 21 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" | 
| 22 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" | 
| 23 #include "chrome/browser/mac/security_wrappers.h" | 22 #include "chrome/browser/mac/security_wrappers.h" | 
| 24 #include "components/password_manager/core/browser/login_database.h" | 23 #include "components/password_manager/core/browser/login_database.h" | 
| 25 #include "components/password_manager/core/browser/password_store_change.h" | 24 #include "components/password_manager/core/browser/password_store_change.h" | 
| 26 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" | 
| 27 #include "crypto/apple_keychain.h" | 26 #include "crypto/apple_keychain.h" | 
| 28 | 27 | 
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 if (base_form.origin == (*i)->origin) { | 410 if (base_form.origin == (*i)->origin) { | 
| 412 return *i; | 411 return *i; | 
| 413 } else if (!partial_match) { | 412 } else if (!partial_match) { | 
| 414 partial_match = *i; | 413 partial_match = *i; | 
| 415 } | 414 } | 
| 416 } | 415 } | 
| 417 } | 416 } | 
| 418 return partial_match; | 417 return partial_match; | 
| 419 } | 418 } | 
| 420 | 419 | 
| 421 // Returns entries from |forms| that are blacklist entries, after removing | 420 // Moves entries from |forms| that are blacklist entries into |blacklist|. | 
| 422 // them from |forms|. | 421 void ExtractBlacklistForms(ScopedVector<autofill::PasswordForm>* forms, | 
| 423 std::vector<PasswordForm*> ExtractBlacklistForms( | 422 ScopedVector<autofill::PasswordForm>* blacklist) { | 
| 424 std::vector<PasswordForm*>* forms) { | 423 blacklist->reserve(blacklist->size() + forms->size()); | 
| 425 std::vector<PasswordForm*> blacklist_forms; | 424 ScopedVector<autofill::PasswordForm> non_blacklist; | 
| 426 for (std::vector<PasswordForm*>::iterator i = forms->begin(); | 425 for (auto& form : *forms) { | 
| 427 i != forms->end();) { | 426 if (form->blacklisted_by_user) | 
| 428 PasswordForm* form = *i; | 427 blacklist->push_back(form); | 
| 429 if (form->blacklisted_by_user) { | 428 else | 
| 430 blacklist_forms.push_back(form); | 429 non_blacklist.push_back(form); | 
| 431 i = forms->erase(i); | 430 form = nullptr; | 
| 
vasilii
2015/01/27 20:45:51
you could weak_clear |forms| instead.
 
vabr (Chromium)
2015/01/28 13:27:36
I could, but that extends the period of time when
 
vasilii
2015/01/28 15:09:03
It's performance related. You know that |forms| co
 
vabr (Chromium)
2015/01/28 16:36:27
To record our offline discussion: a benchmark run
 | |
| 432 } else { | |
| 433 ++i; | |
| 434 } | |
| 435 } | 431 } | 
| 436 return blacklist_forms; | 432 forms->swap(non_blacklist); | 
| 437 } | 433 } | 
| 438 | 434 | 
| 439 // Deletes and removes from v any element that exists in s. | 435 // Takes |keychain_forms| and |database_forms| and moves the following 2 types | 
| 440 template <class T> | 436 // of forms to |merged_forms|: (1) blacklisted |database_forms|, (2) | 
| 441 void DeleteVectorElementsInSet(std::vector<T*>* v, const std::set<T*>& s) { | 437 // |database_forms| which have a corresponding entry in |keychain_forms|. The | 
| 442 for (typename std::vector<T*>::iterator i = v->begin(); i != v->end();) { | 438 // database forms of type (2) have their password value updated from the | 
| 443 T* element = *i; | 439 // corresponding keychain form, and all the keychain forms corresponding to some | 
| 444 if (s.find(element) != s.end()) { | 440 // database form are removed from |keychain_forms| and deleted. | 
| 445 delete element; | 441 void MergePasswordForms(ScopedVector<autofill::PasswordForm>* keychain_forms, | 
| 446 i = v->erase(i); | 442 ScopedVector<autofill::PasswordForm>* database_forms, | 
| 447 } else { | 443 ScopedVector<autofill::PasswordForm>* merged_forms) { | 
| 448 ++i; | |
| 449 } | |
| 450 } | |
| 451 } | |
| 452 | |
| 453 void MergePasswordForms(std::vector<PasswordForm*>* keychain_forms, | |
| 454 std::vector<PasswordForm*>* database_forms, | |
| 455 std::vector<PasswordForm*>* merged_forms) { | |
| 456 // Pull out the database blacklist items, since they are used as-is rather | 444 // Pull out the database blacklist items, since they are used as-is rather | 
| 457 // than being merged with keychain forms. | 445 // than being merged with keychain forms. | 
| 458 std::vector<PasswordForm*> database_blacklist_forms = | 446 ExtractBlacklistForms(database_forms, merged_forms); | 
| 459 ExtractBlacklistForms(database_forms); | |
| 460 | 447 | 
| 461 // Merge the normal entries. | 448 // Merge the normal entries. | 
| 462 std::set<PasswordForm*> used_keychain_forms; | 449 ScopedVector<autofill::PasswordForm> unused_database_forms; | 
| 463 for (std::vector<PasswordForm*>::iterator i = database_forms->begin(); | 450 unused_database_forms.reserve(database_forms->size()); | 
| 464 i != database_forms->end();) { | 451 std::set<autofill::PasswordForm*> used_keychain_forms; | 
| 465 PasswordForm* db_form = *i; | 452 for (auto& db_form : *database_forms) { | 
| 466 PasswordForm* best_match = BestKeychainFormForForm(*db_form, | 453 PasswordForm* best_match = | 
| 467 keychain_forms); | 454 BestKeychainFormForForm(*db_form, &keychain_forms->get()); | 
| 468 if (best_match) { | 455 if (best_match) { | 
| 469 used_keychain_forms.insert(best_match); | 456 used_keychain_forms.insert(best_match); | 
| 470 db_form->password_value = best_match->password_value; | 457 db_form->password_value = best_match->password_value; | 
| 471 merged_forms->push_back(db_form); | 458 merged_forms->push_back(db_form); | 
| 472 i = database_forms->erase(i); | |
| 473 } else { | 459 } else { | 
| 474 ++i; | 460 unused_database_forms.push_back(db_form); | 
| 461 } | |
| 462 db_form = nullptr; | |
| 
vasilii
2015/01/27 20:45:51
again I'd prefer weak_clear.
 
vabr (Chromium)
2015/01/28 13:27:35
Please see my response above.
 | |
| 463 } | |
| 464 database_forms->swap(unused_database_forms); | |
| 465 | |
| 466 // Clear out all the Keychain entries we used. | |
| 467 ScopedVector<autofill::PasswordForm> unused_keychain_forms; | |
| 468 unused_keychain_forms.reserve(keychain_forms->size()); | |
| 469 for (auto& keychain_form : *keychain_forms) { | |
| 470 if (!ContainsKey(used_keychain_forms, keychain_form)) { | |
| 471 using std::swap; | |
| 
vasilii
2015/01/27 20:45:51
excessive here.
 
vabr (Chromium)
2015/01/28 13:27:35
Done.
 | |
| 472 unused_keychain_forms.push_back(nullptr); | |
| 473 swap(keychain_form, unused_keychain_forms.back()); | |
| 
vasilii
2015/01/27 20:45:51
It's easier to understand
unused_keychain_forms.p
 
vabr (Chromium)
2015/01/28 13:27:36
Agreed. This was an overlooked relic from a past p
 | |
| 475 } | 474 } | 
| 476 } | 475 } | 
| 477 | 476 keychain_forms->swap(unused_keychain_forms); | 
| 478 // Add in the blacklist entries from the database. | |
| 479 merged_forms->insert(merged_forms->end(), | |
| 480 database_blacklist_forms.begin(), | |
| 481 database_blacklist_forms.end()); | |
| 482 | |
| 483 // Clear out all the Keychain entries we used. | |
| 484 DeleteVectorElementsInSet(keychain_forms, used_keychain_forms); | |
| 485 } | 477 } | 
| 486 | 478 | 
| 487 std::vector<ItemFormPair> ExtractAllKeychainItemAttributesIntoPasswordForms( | 479 std::vector<ItemFormPair> ExtractAllKeychainItemAttributesIntoPasswordForms( | 
| 488 std::vector<SecKeychainItemRef>* keychain_items, | 480 std::vector<SecKeychainItemRef>* keychain_items, | 
| 489 const AppleKeychain& keychain) { | 481 const AppleKeychain& keychain) { | 
| 490 DCHECK(keychain_items); | 482 DCHECK(keychain_items); | 
| 491 MacKeychainPasswordFormAdapter keychain_adapter(&keychain); | 483 MacKeychainPasswordFormAdapter keychain_adapter(&keychain); | 
| 492 *keychain_items = keychain_adapter.GetAllPasswordFormKeychainItems(); | 484 *keychain_items = keychain_adapter.GetAllPasswordFormKeychainItems(); | 
| 493 std::vector<ItemFormPair> item_form_pairs; | 485 std::vector<ItemFormPair> item_form_pairs; | 
| 494 for (std::vector<SecKeychainItemRef>::iterator i = keychain_items->begin(); | 486 for (std::vector<SecKeychainItemRef>::iterator i = keychain_items->begin(); | 
| 495 i != keychain_items->end(); ++i) { | 487 i != keychain_items->end(); ++i) { | 
| 496 PasswordForm* form_without_password = new PasswordForm(); | 488 PasswordForm* form_without_password = new PasswordForm(); | 
| 497 internal_keychain_helpers::FillPasswordFormFromKeychainItem( | 489 internal_keychain_helpers::FillPasswordFormFromKeychainItem( | 
| 498 keychain, | 490 keychain, | 
| 499 *i, | 491 *i, | 
| 500 form_without_password, | 492 form_without_password, | 
| 501 false); // Load password attributes, but not password data. | 493 false); // Load password attributes, but not password data. | 
| 502 item_form_pairs.push_back(std::make_pair(&(*i), form_without_password)); | 494 item_form_pairs.push_back(std::make_pair(&(*i), form_without_password)); | 
| 503 } | 495 } | 
| 504 return item_form_pairs; | 496 return item_form_pairs; | 
| 505 } | 497 } | 
| 506 | 498 | 
| 507 std::vector<PasswordForm*> GetPasswordsForForms( | 499 void GetPasswordsForForms(const AppleKeychain& keychain, | 
| 508 const AppleKeychain& keychain, | 500 ScopedVector<autofill::PasswordForm>* database_forms, | 
| 509 std::vector<PasswordForm*>* database_forms) { | 501 ScopedVector<autofill::PasswordForm>* passwords) { | 
| 510 // First load the attributes of all items in the keychain without loading | 502 // First load the attributes of all items in the keychain without loading | 
| 511 // their password data, and then match items in |database_forms| against them. | 503 // their password data, and then match items in |database_forms| against them. | 
| 512 // This avoids individually searching through the keychain for passwords | 504 // This avoids individually searching through the keychain for passwords | 
| 513 // matching each form in |database_forms|, and results in a significant | 505 // matching each form in |database_forms|, and results in a significant | 
| 514 // performance gain, replacing O(N) keychain search operations with a single | 506 // performance gain, replacing O(N) keychain search operations with a single | 
| 515 // operation that loads all keychain items, and then selective reads of only | 507 // operation that loads all keychain items, and then selective reads of only | 
| 516 // the relevant passwords. See crbug.com/263685. | 508 // the relevant passwords. See crbug.com/263685. | 
| 517 std::vector<SecKeychainItemRef> keychain_items; | 509 std::vector<SecKeychainItemRef> keychain_items; | 
| 518 std::vector<ItemFormPair> item_form_pairs = | 510 std::vector<ItemFormPair> item_form_pairs = | 
| 519 ExtractAllKeychainItemAttributesIntoPasswordForms(&keychain_items, | 511 ExtractAllKeychainItemAttributesIntoPasswordForms(&keychain_items, | 
| 520 keychain); | 512 keychain); | 
| 521 | 513 | 
| 522 // Next, compare the attributes of the PasswordForms in |database_forms| | 514 // Next, compare the attributes of the PasswordForms in |database_forms| | 
| 523 // against those in |item_form_pairs|, and extract password data for each | 515 // against those in |item_form_pairs|, and extract password data for each | 
| 524 // matching PasswordForm using its corresponding SecKeychainItemRef. | 516 // matching PasswordForm using its corresponding SecKeychainItemRef. | 
| 525 std::vector<PasswordForm*> merged_forms; | 517 ScopedVector<autofill::PasswordForm> unused_db_forms; | 
| 526 for (std::vector<PasswordForm*>::iterator i = database_forms->begin(); | 518 unused_db_forms.reserve(database_forms->size()); | 
| 527 i != database_forms->end();) { | 519 for (auto& db_form : *database_forms) { | 
| 528 std::vector<PasswordForm*> db_form_container(1, *i); | 520 ScopedVector<autofill::PasswordForm> keychain_matches; | 
| 529 std::vector<PasswordForm*> keychain_matches = | 521 ExtractPasswordsMergeableWithForm(keychain, item_form_pairs, *db_form, | 
| 530 ExtractPasswordsMergeableWithForm(keychain, item_form_pairs, **i); | 522 &keychain_matches); | 
| 531 MergePasswordForms(&keychain_matches, &db_form_container, &merged_forms); | 523 | 
| 532 if (db_form_container.empty()) { | 524 ScopedVector<autofill::PasswordForm> db_form_container; | 
| 533 i = database_forms->erase(i); | 525 db_form_container.push_back(db_form); | 
| 534 } else { | 526 db_form = nullptr; | 
| 
vasilii
2015/01/27 20:45:51
I think weak_clear is better here.
 
vabr (Chromium)
2015/01/28 13:27:35
Please see my answer above.
 | |
| 535 ++i; | 527 MergePasswordForms(&keychain_matches, &db_form_container, passwords); | 
| 536 } | 528 unused_db_forms.insert(unused_db_forms.end(), db_form_container.begin(), | 
| 537 STLDeleteElements(&keychain_matches); | 529 db_form_container.end()); | 
| 530 db_form_container.weak_clear(); | |
| 538 } | 531 } | 
| 532 database_forms->swap(unused_db_forms); | |
| 539 | 533 | 
| 540 // Clean up temporary PasswordForms and SecKeychainItemRefs. | |
| 541 STLDeleteContainerPairSecondPointers(item_form_pairs.begin(), | 534 STLDeleteContainerPairSecondPointers(item_form_pairs.begin(), | 
| 542 item_form_pairs.end()); | 535 item_form_pairs.end()); | 
| 543 for (std::vector<SecKeychainItemRef>::iterator i = keychain_items.begin(); | 536 for (auto& item : keychain_items) { | 
| 
vasilii
2015/01/27 20:45:51
Here I'd prefer "SecKeychainItemRef item" but not
 
vabr (Chromium)
2015/01/28 13:27:35
Done.
 | |
| 544 i != keychain_items.end(); ++i) { | 537 keychain.Free(item); | 
| 545 keychain.Free(*i); | |
| 546 } | 538 } | 
| 547 return merged_forms; | |
| 548 } | 539 } | 
| 549 | 540 | 
| 550 // TODO(stuartmorgan): signon_realm for proxies is not yet supported. | 541 // TODO(stuartmorgan): signon_realm for proxies is not yet supported. | 
| 551 bool ExtractSignonRealmComponents(const std::string& signon_realm, | 542 bool ExtractSignonRealmComponents(const std::string& signon_realm, | 
| 552 std::string* server, | 543 std::string* server, | 
| 553 UInt32* port, | 544 UInt32* port, | 
| 554 bool* is_secure, | 545 bool* is_secure, | 
| 555 std::string* security_domain) { | 546 std::string* security_domain) { | 
| 556 // The signon_realm will be the Origin portion of a URL for an HTML form, | 547 // The signon_realm will be the Origin portion of a URL for an HTML form, | 
| 557 // and the same but with the security domain as a path for HTTP auth. | 548 // and the same but with the security domain as a path for HTTP auth. | 
| (...skipping 25 matching lines...) Expand all Loading... | |
| 583 UInt32 port; | 574 UInt32 port; | 
| 584 bool is_secure; | 575 bool is_secure; | 
| 585 if (!ExtractSignonRealmComponents(query_form.signon_realm, &server, &port, | 576 if (!ExtractSignonRealmComponents(query_form.signon_realm, &server, &port, | 
| 586 &is_secure, &security_domain)) { | 577 &is_secure, &security_domain)) { | 
| 587 return false; | 578 return false; | 
| 588 } | 579 } | 
| 589 return internal_keychain_helpers::FormsMatchForMerge( | 580 return internal_keychain_helpers::FormsMatchForMerge( | 
| 590 query_form, other_form, STRICT_FORM_MATCH); | 581 query_form, other_form, STRICT_FORM_MATCH); | 
| 591 } | 582 } | 
| 592 | 583 | 
| 593 std::vector<PasswordForm*> ExtractPasswordsMergeableWithForm( | 584 void ExtractPasswordsMergeableWithForm( | 
| 594 const AppleKeychain& keychain, | 585 const AppleKeychain& keychain, | 
| 595 const std::vector<ItemFormPair>& item_form_pairs, | 586 const std::vector<ItemFormPair>& item_form_pairs, | 
| 596 const PasswordForm& query_form) { | 587 const PasswordForm& query_form, | 
| 597 std::vector<PasswordForm*> matches; | 588 ScopedVector<autofill::PasswordForm>* matches) { | 
| 
vasilii
2015/01/27 20:45:51
returning this object would simplify the caller.
 
vabr (Chromium)
2015/01/28 13:27:35
Done.
(I misread the definition of ScopedVector a
 | |
| 598 for (std::vector<ItemFormPair>::const_iterator i = item_form_pairs.begin(); | 589 for (std::vector<ItemFormPair>::const_iterator i = item_form_pairs.begin(); | 
| 599 i != item_form_pairs.end(); ++i) { | 590 i != item_form_pairs.end(); ++i) { | 
| 600 if (FormIsValidAndMatchesOtherForm(query_form, *(i->second))) { | 591 if (FormIsValidAndMatchesOtherForm(query_form, *(i->second))) { | 
| 601 // Create a new object, since the caller is responsible for deleting the | 592 // Create a new object, since the caller is responsible for deleting the | 
| 602 // returned forms. | 593 // returned forms. | 
| 603 scoped_ptr<PasswordForm> form_with_password(new PasswordForm()); | 594 scoped_ptr<PasswordForm> form_with_password(new PasswordForm()); | 
| 604 internal_keychain_helpers::FillPasswordFormFromKeychainItem( | 595 internal_keychain_helpers::FillPasswordFormFromKeychainItem( | 
| 605 keychain, | 596 keychain, | 
| 606 *(i->first), | 597 *(i->first), | 
| 607 form_with_password.get(), | 598 form_with_password.get(), | 
| 608 true); // Load password attributes and data. | 599 true); // Load password attributes and data. | 
| 609 // Do not include blacklisted items found in the keychain. | 600 // Do not include blacklisted items found in the keychain. | 
| 610 if (!form_with_password->blacklisted_by_user) | 601 if (!form_with_password->blacklisted_by_user) | 
| 611 matches.push_back(form_with_password.release()); | 602 matches->push_back(form_with_password.release()); | 
| 612 } | 603 } | 
| 613 } | 604 } | 
| 614 return matches; | |
| 615 } | 605 } | 
| 616 | 606 | 
| 617 } // namespace internal_keychain_helpers | 607 } // namespace internal_keychain_helpers | 
| 618 | 608 | 
| 619 #pragma mark - | 609 #pragma mark - | 
| 620 | 610 | 
| 621 MacKeychainPasswordFormAdapter::MacKeychainPasswordFormAdapter( | 611 MacKeychainPasswordFormAdapter::MacKeychainPasswordFormAdapter( | 
| 622 const AppleKeychain* keychain) | 612 const AppleKeychain* keychain) | 
| 623 : keychain_(keychain), finds_only_owned_(false) { | 613 : keychain_(keychain), finds_only_owned_(false) { | 
| 624 } | 614 } | 
| 625 | 615 | 
| 626 std::vector<PasswordForm*> MacKeychainPasswordFormAdapter::PasswordsFillingForm( | 616 // Gets keychain items corresponding to |signon_realm| and |scheme|, converts | 
| 617 // them into PasswordForms and appends them to |forms|. | |
| 618 void MacKeychainPasswordFormAdapter::PasswordsFillingForm( | |
| 627 const std::string& signon_realm, | 619 const std::string& signon_realm, | 
| 628 PasswordForm::Scheme scheme) { | 620 PasswordForm::Scheme scheme, | 
| 621 ScopedVector<autofill::PasswordForm>* forms) { | |
| 629 std::vector<SecKeychainItemRef> keychain_items = | 622 std::vector<SecKeychainItemRef> keychain_items = | 
| 630 MatchingKeychainItems(signon_realm, scheme, NULL, NULL); | 623 MatchingKeychainItems(signon_realm, scheme, NULL, NULL); | 
| 631 | 624 ConvertKeychainItemsToForms(&keychain_items, forms); | 
| 632 return ConvertKeychainItemsToForms(&keychain_items); | |
| 633 } | 625 } | 
| 634 | 626 | 
| 635 bool MacKeychainPasswordFormAdapter::HasPasswordExactlyMatchingForm( | 627 bool MacKeychainPasswordFormAdapter::HasPasswordExactlyMatchingForm( | 
| 636 const PasswordForm& query_form) { | 628 const PasswordForm& query_form) { | 
| 637 SecKeychainItemRef keychain_item = KeychainItemForForm(query_form); | 629 SecKeychainItemRef keychain_item = KeychainItemForForm(query_form); | 
| 638 if (keychain_item) { | 630 if (keychain_item) { | 
| 639 keychain_->Free(keychain_item); | 631 keychain_->Free(keychain_item); | 
| 640 return true; | 632 return true; | 
| 641 } | 633 } | 
| 642 return false; | 634 return false; | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 674 &supported_auth_types[i], | 666 &supported_auth_types[i], | 
| 675 NULL, | 667 NULL, | 
| 676 NULL, | 668 NULL, | 
| 677 NULL, | 669 NULL, | 
| 678 creator ? &creator : NULL); | 670 creator ? &creator : NULL); | 
| 679 keychain_search.FindMatchingItems(&matches); | 671 keychain_search.FindMatchingItems(&matches); | 
| 680 } | 672 } | 
| 681 return matches; | 673 return matches; | 
| 682 } | 674 } | 
| 683 | 675 | 
| 684 std::vector<PasswordForm*> | 676 void MacKeychainPasswordFormAdapter::GetAllPasswordFormPasswords( | 
| 685 MacKeychainPasswordFormAdapter::GetAllPasswordFormPasswords() { | 677 ScopedVector<autofill::PasswordForm>* forms) { | 
| 686 std::vector<SecKeychainItemRef> items = GetAllPasswordFormKeychainItems(); | 678 std::vector<SecKeychainItemRef> items = GetAllPasswordFormKeychainItems(); | 
| 687 return ConvertKeychainItemsToForms(&items); | 679 return ConvertKeychainItemsToForms(&items, forms); | 
| 688 } | 680 } | 
| 689 | 681 | 
| 690 bool MacKeychainPasswordFormAdapter::AddPassword(const PasswordForm& form) { | 682 bool MacKeychainPasswordFormAdapter::AddPassword(const PasswordForm& form) { | 
| 691 // We should never be trying to store a blacklist in the keychain. | 683 // We should never be trying to store a blacklist in the keychain. | 
| 692 DCHECK(!form.blacklisted_by_user); | 684 DCHECK(!form.blacklisted_by_user); | 
| 693 | 685 | 
| 694 std::string server; | 686 std::string server; | 
| 695 std::string security_domain; | 687 std::string security_domain; | 
| 696 UInt32 port; | 688 UInt32 port; | 
| 697 bool is_secure; | 689 bool is_secure; | 
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 738 OSStatus result = keychain_->ItemDelete(keychain_item); | 730 OSStatus result = keychain_->ItemDelete(keychain_item); | 
| 739 keychain_->Free(keychain_item); | 731 keychain_->Free(keychain_item); | 
| 740 return result == noErr; | 732 return result == noErr; | 
| 741 } | 733 } | 
| 742 | 734 | 
| 743 void MacKeychainPasswordFormAdapter::SetFindsOnlyOwnedItems( | 735 void MacKeychainPasswordFormAdapter::SetFindsOnlyOwnedItems( | 
| 744 bool finds_only_owned) { | 736 bool finds_only_owned) { | 
| 745 finds_only_owned_ = finds_only_owned; | 737 finds_only_owned_ = finds_only_owned; | 
| 746 } | 738 } | 
| 747 | 739 | 
| 748 std::vector<PasswordForm*> | 740 void MacKeychainPasswordFormAdapter::ConvertKeychainItemsToForms( | 
| 749 MacKeychainPasswordFormAdapter::ConvertKeychainItemsToForms( | 741 std::vector<SecKeychainItemRef>* items, | 
| 750 std::vector<SecKeychainItemRef>* items) { | 742 ScopedVector<autofill::PasswordForm>* forms) { | 
| 
vasilii
2015/01/27 20:45:51
returning this would simplify the code.
 
vabr (Chromium)
2015/01/28 13:27:35
Done.
 | |
| 751 std::vector<PasswordForm*> keychain_forms; | 743 for (const auto& item : *items) { | 
| 
vasilii
2015/01/27 20:45:51
You are iterating over pointers. I'd prefer "SecKe
 
vabr (Chromium)
2015/01/28 13:27:35
Done.
 | |
| 752 for (std::vector<SecKeychainItemRef>::const_iterator i = items->begin(); | 744 scoped_ptr<PasswordForm> form(new PasswordForm()); | 
| 753 i != items->end(); ++i) { | |
| 754 PasswordForm* form = new PasswordForm(); | |
| 755 if (internal_keychain_helpers::FillPasswordFormFromKeychainItem( | 745 if (internal_keychain_helpers::FillPasswordFormFromKeychainItem( | 
| 756 *keychain_, *i, form, true)) { | 746 *keychain_, item, form.get(), true)) { | 
| 757 keychain_forms.push_back(form); | 747 forms->push_back(form.release()); | 
| 758 } | 748 } | 
| 759 keychain_->Free(*i); | 749 keychain_->Free(item); | 
| 760 } | 750 } | 
| 761 items->clear(); | 751 items->clear(); | 
| 762 return keychain_forms; | |
| 763 } | 752 } | 
| 764 | 753 | 
| 765 SecKeychainItemRef MacKeychainPasswordFormAdapter::KeychainItemForForm( | 754 SecKeychainItemRef MacKeychainPasswordFormAdapter::KeychainItemForForm( | 
| 766 const PasswordForm& form) { | 755 const PasswordForm& form) { | 
| 767 // We don't store blacklist entries in the keychain, so the answer to "what | 756 // We don't store blacklist entries in the keychain, so the answer to "what | 
| 768 // Keychain item goes with this form" is always "nothing" for blacklists. | 757 // Keychain item goes with this form" is always "nothing" for blacklists. | 
| 769 if (form.blacklisted_by_user) { | 758 if (form.blacklisted_by_user) { | 
| 770 return NULL; | 759 return NULL; | 
| 771 } | 760 } | 
| 772 | 761 | 
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 976 | 965 | 
| 977 changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form)); | 966 changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form)); | 
| 978 } | 967 } | 
| 979 return changes; | 968 return changes; | 
| 980 } | 969 } | 
| 981 | 970 | 
| 982 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsCreatedBetweenImpl( | 971 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsCreatedBetweenImpl( | 
| 983 base::Time delete_begin, | 972 base::Time delete_begin, | 
| 984 base::Time delete_end) { | 973 base::Time delete_end) { | 
| 985 PasswordStoreChangeList changes; | 974 PasswordStoreChangeList changes; | 
| 986 ScopedVector<PasswordForm> forms; | 975 ScopedVector<PasswordForm> forms_to_remove; | 
| 987 if (login_metadata_db_ && | 976 if (login_metadata_db_ && | 
| 988 login_metadata_db_->GetLoginsCreatedBetween(delete_begin, delete_end, | 977 login_metadata_db_->GetLoginsCreatedBetween(delete_begin, delete_end, | 
| 989 &forms.get()) && | 978 &forms_to_remove) && | 
| 990 login_metadata_db_->RemoveLoginsCreatedBetween(delete_begin, | 979 login_metadata_db_->RemoveLoginsCreatedBetween(delete_begin, | 
| 991 delete_end)) { | 980 delete_end)) { | 
| 992 RemoveKeychainForms(forms.get()); | 981 RemoveKeychainForms(forms_to_remove.get()); | 
| 993 CleanOrphanedForms(&forms.get()); | 982 CleanOrphanedForms(&forms_to_remove); // Add the orphaned forms. | 
| 994 changes = FormsToRemoveChangeList(forms.get()); | 983 changes = FormsToRemoveChangeList(forms_to_remove.get()); | 
| 995 LogStatsForBulkDeletion(changes.size()); | 984 LogStatsForBulkDeletion(changes.size()); | 
| 996 } | 985 } | 
| 997 return changes; | 986 return changes; | 
| 998 } | 987 } | 
| 999 | 988 | 
| 1000 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsSyncedBetweenImpl( | 989 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsSyncedBetweenImpl( | 
| 1001 base::Time delete_begin, | 990 base::Time delete_begin, | 
| 1002 base::Time delete_end) { | 991 base::Time delete_end) { | 
| 1003 PasswordStoreChangeList changes; | 992 PasswordStoreChangeList changes; | 
| 1004 ScopedVector<PasswordForm> forms; | 993 ScopedVector<PasswordForm> forms_to_remove; | 
| 1005 if (login_metadata_db_ && | 994 if (login_metadata_db_ && | 
| 1006 login_metadata_db_->GetLoginsSyncedBetween(delete_begin, delete_end, | 995 login_metadata_db_->GetLoginsSyncedBetween(delete_begin, delete_end, | 
| 1007 &forms.get()) && | 996 &forms_to_remove) && | 
| 1008 login_metadata_db_->RemoveLoginsSyncedBetween(delete_begin, delete_end)) { | 997 login_metadata_db_->RemoveLoginsSyncedBetween(delete_begin, delete_end)) { | 
| 1009 RemoveKeychainForms(forms.get()); | 998 RemoveKeychainForms(forms_to_remove.get()); | 
| 1010 CleanOrphanedForms(&forms.get()); | 999 CleanOrphanedForms(&forms_to_remove); // Add the orphaned forms_to_remove. | 
| 1011 changes = FormsToRemoveChangeList(forms.get()); | 1000 changes = FormsToRemoveChangeList(forms_to_remove.get()); | 
| 1012 LogStatsForBulkDeletionDuringRollback(changes.size()); | 1001 LogStatsForBulkDeletionDuringRollback(changes.size()); | 
| 1013 } | 1002 } | 
| 1014 return changes; | 1003 return changes; | 
| 1015 } | 1004 } | 
| 1016 | 1005 | 
| 1017 void PasswordStoreMac::GetLoginsImpl( | 1006 void PasswordStoreMac::GetLoginsImpl( | 
| 1018 const autofill::PasswordForm& form, | 1007 const autofill::PasswordForm& form, | 
| 1019 AuthorizationPromptPolicy prompt_policy, | 1008 AuthorizationPromptPolicy prompt_policy, | 
| 1020 const ConsumerCallbackRunner& callback_runner) { | 1009 const ConsumerCallbackRunner& callback_runner) { | 
| 1021 chrome::ScopedSecKeychainSetUserInteractionAllowed user_interaction_allowed( | 1010 chrome::ScopedSecKeychainSetUserInteractionAllowed user_interaction_allowed( | 
| 1022 prompt_policy == ALLOW_PROMPT); | 1011 prompt_policy == ALLOW_PROMPT); | 
| 1023 | 1012 | 
| 1024 if (!login_metadata_db_) { | 1013 if (!login_metadata_db_) { | 
| 1025 callback_runner.Run(std::vector<PasswordForm*>()); | 1014 ScopedVector<autofill::PasswordForm> dummy_matched_forms; | 
| 1015 callback_runner.Run(&dummy_matched_forms); | |
| 1026 return; | 1016 return; | 
| 1027 } | 1017 } | 
| 1028 | 1018 | 
| 1029 ScopedVector<PasswordForm> database_forms; | 1019 ScopedVector<PasswordForm> database_forms; | 
| 1030 login_metadata_db_->GetLogins(form, &database_forms.get()); | 1020 login_metadata_db_->GetLogins(form, &database_forms); | 
| 1031 | 1021 | 
| 1032 // Let's gather all signon realms we want to match with keychain entries. | 1022 // Let's gather all signon realms we want to match with keychain entries. | 
| 1033 std::set<std::string> realm_set; | 1023 std::set<std::string> realm_set; | 
| 1034 realm_set.insert(form.signon_realm); | 1024 realm_set.insert(form.signon_realm); | 
| 1035 for (std::vector<PasswordForm*>::const_iterator db_form = | 1025 for (const auto& db_form : database_forms) { | 
| 
vasilii
2015/01/27 20:45:51
const reference to pointer seems to be an overhead
 
vabr (Chromium)
2015/01/28 13:27:36
Done.
 | |
| 1036 database_forms.begin(); | |
| 1037 db_form != database_forms.end(); | |
| 1038 ++db_form) { | |
| 1039 // TODO(vabr): We should not be getting different schemes here. | 1026 // TODO(vabr): We should not be getting different schemes here. | 
| 1040 // http://crbug.com/340112 | 1027 // http://crbug.com/340112 | 
| 1041 if (form.scheme != (*db_form)->scheme) | 1028 if (form.scheme != db_form->scheme) | 
| 1042 continue; // Forms with different schemes never match. | 1029 continue; // Forms with different schemes never match. | 
| 1043 const std::string& original_singon_realm((*db_form)->original_signon_realm); | 1030 const std::string& original_singon_realm(db_form->original_signon_realm); | 
| 1044 if (!original_singon_realm.empty()) | 1031 if (!original_singon_realm.empty()) | 
| 1045 realm_set.insert(original_singon_realm); | 1032 realm_set.insert(original_singon_realm); | 
| 1046 } | 1033 } | 
| 1047 std::vector<PasswordForm*> keychain_forms; | 1034 ScopedVector<autofill::PasswordForm> keychain_forms; | 
| 1048 for (std::set<std::string>::const_iterator realm = realm_set.begin(); | 1035 for (std::set<std::string>::const_iterator realm = realm_set.begin(); | 
| 1049 realm != realm_set.end(); | 1036 realm != realm_set.end(); | 
| 1050 ++realm) { | 1037 ++realm) { | 
| 1051 MacKeychainPasswordFormAdapter keychain_adapter(keychain_.get()); | 1038 MacKeychainPasswordFormAdapter keychain_adapter(keychain_.get()); | 
| 1052 std::vector<PasswordForm*> temp_keychain_forms = | 1039 keychain_adapter.PasswordsFillingForm(*realm, form.scheme, &keychain_forms); | 
| 1053 keychain_adapter.PasswordsFillingForm(*realm, form.scheme); | |
| 1054 keychain_forms.insert(keychain_forms.end(), | |
| 1055 temp_keychain_forms.begin(), | |
| 1056 temp_keychain_forms.end()); | |
| 1057 } | 1040 } | 
| 1058 | 1041 | 
| 1059 std::vector<PasswordForm*> matched_forms; | 1042 ScopedVector<autofill::PasswordForm> matched_forms; | 
| 1060 internal_keychain_helpers::MergePasswordForms(&keychain_forms, | 1043 internal_keychain_helpers::MergePasswordForms( | 
| 1061 &database_forms.get(), | 1044 &keychain_forms, &database_forms, &matched_forms); | 
| 1062 &matched_forms); | |
| 1063 | 1045 | 
| 1064 // Strip any blacklist entries out of the unused Keychain array, then take | 1046 // Strip any blacklist entries out of the unused Keychain array, then take | 
| 1065 // all the entries that are left (which we can use as imported passwords). | 1047 // all the entries that are left (which we can use as imported passwords). | 
| 1066 ScopedVector<PasswordForm> keychain_blacklist_forms; | 1048 ScopedVector<PasswordForm> keychain_blacklist_forms; | 
| 1067 internal_keychain_helpers::ExtractBlacklistForms(&keychain_forms).swap( | 1049 internal_keychain_helpers::ExtractBlacklistForms(&keychain_forms, | 
| 1068 keychain_blacklist_forms.get()); | 1050 &keychain_blacklist_forms); | 
| 1069 matched_forms.insert(matched_forms.end(), | 1051 matched_forms.insert(matched_forms.end(), | 
| 1070 keychain_forms.begin(), | 1052 keychain_forms.begin(), | 
| 1071 keychain_forms.end()); | 1053 keychain_forms.end()); | 
| 1072 keychain_forms.clear(); | 1054 keychain_forms.weak_clear(); | 
| 1073 | 1055 | 
| 1074 if (!database_forms.empty()) { | 1056 if (!database_forms.empty()) { | 
| 1075 RemoveDatabaseForms(database_forms.get()); | 1057 RemoveDatabaseForms(database_forms.get()); | 
| 1076 NotifyLoginsChanged(FormsToRemoveChangeList(database_forms.get())); | 1058 NotifyLoginsChanged(FormsToRemoveChangeList(database_forms.get())); | 
| 1077 } | 1059 } | 
| 1078 | 1060 | 
| 1079 callback_runner.Run(matched_forms); | 1061 callback_runner.Run(&matched_forms); | 
| 1080 } | 1062 } | 
| 1081 | 1063 | 
| 1082 void PasswordStoreMac::GetBlacklistLoginsImpl(GetLoginsRequest* request) { | 1064 void PasswordStoreMac::GetBlacklistLoginsImpl(GetLoginsRequest* request) { | 
| 1083 FillBlacklistLogins(request->result()); | 1065 ScopedVector<autofill::PasswordForm> obtained_forms; | 
| 1066 FillBlacklistLogins(&obtained_forms); | |
| 1067 request->result()->swap(obtained_forms.get()); | |
| 1068 obtained_forms.weak_clear(); // TODO(vabr): Change request to have a | |
| 
vasilii
2015/01/27 20:45:51
Seems to be a leak.
 
vabr (Chromium)
2015/01/28 13:27:35
You are right. I honestly don't know what I was th
 | |
| 1069 // ScopedVector instead. | |
| 1084 ForwardLoginsResult(request); | 1070 ForwardLoginsResult(request); | 
| 1085 } | 1071 } | 
| 1086 | 1072 | 
| 1087 void PasswordStoreMac::GetAutofillableLoginsImpl(GetLoginsRequest* request) { | 1073 void PasswordStoreMac::GetAutofillableLoginsImpl(GetLoginsRequest* request) { | 
| 1088 FillAutofillableLogins(request->result()); | 1074 ScopedVector<autofill::PasswordForm> obtained_forms; | 
| 1075 FillAutofillableLogins(&obtained_forms); | |
| 1076 request->result()->swap(obtained_forms.get()); | |
| 1077 obtained_forms.weak_clear(); // TODO(vabr): Change request to have a | |
| 
vasilii
2015/01/27 20:45:51
Same here.
 
vabr (Chromium)
2015/01/28 13:27:35
Done.
 | |
| 1078 // ScopedVector instead. | |
| 1089 ForwardLoginsResult(request); | 1079 ForwardLoginsResult(request); | 
| 1090 } | 1080 } | 
| 1091 | 1081 | 
| 1092 bool PasswordStoreMac::FillAutofillableLogins( | 1082 bool PasswordStoreMac::FillAutofillableLogins( | 
| 1093 std::vector<PasswordForm*>* forms) { | 1083 ScopedVector<autofill::PasswordForm>* forms) { | 
| 1094 DCHECK(thread_->message_loop() == base::MessageLoop::current()); | 1084 DCHECK(thread_->message_loop() == base::MessageLoop::current()); | 
| 1095 | 1085 | 
| 1096 ScopedVector<PasswordForm> database_forms; | 1086 ScopedVector<PasswordForm> database_forms; | 
| 1097 if (!login_metadata_db_ || | 1087 if (!login_metadata_db_ || | 
| 1098 !login_metadata_db_->GetAutofillableLogins(&database_forms.get())) | 1088 !login_metadata_db_->GetAutofillableLogins(&database_forms)) | 
| 1099 return false; | 1089 return false; | 
| 1100 | 1090 | 
| 1101 std::vector<PasswordForm*> merged_forms = | 1091 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, | 
| 1102 internal_keychain_helpers::GetPasswordsForForms(*keychain_, | 1092 forms); | 
| 1103 &database_forms.get()); | |
| 1104 | 1093 | 
| 1105 if (!database_forms.empty()) { | 1094 if (!database_forms.empty()) { | 
| 1106 RemoveDatabaseForms(database_forms.get()); | 1095 RemoveDatabaseForms(database_forms.get()); | 
| 1107 NotifyLoginsChanged(FormsToRemoveChangeList(database_forms.get())); | 1096 NotifyLoginsChanged(FormsToRemoveChangeList(database_forms.get())); | 
| 1108 } | 1097 } | 
| 1109 | 1098 | 
| 1110 forms->insert(forms->end(), merged_forms.begin(), merged_forms.end()); | |
| 1111 return true; | 1099 return true; | 
| 1112 } | 1100 } | 
| 1113 | 1101 | 
| 1114 bool PasswordStoreMac::FillBlacklistLogins( | 1102 bool PasswordStoreMac::FillBlacklistLogins( | 
| 1115 std::vector<PasswordForm*>* forms) { | 1103 ScopedVector<autofill::PasswordForm>* forms) { | 
| 1116 DCHECK(thread_->message_loop() == base::MessageLoop::current()); | 1104 DCHECK(thread_->message_loop() == base::MessageLoop::current()); | 
| 1117 return login_metadata_db_ && login_metadata_db_->GetBlacklistLogins(forms); | 1105 return login_metadata_db_ && login_metadata_db_->GetBlacklistLogins(forms); | 
| 1118 } | 1106 } | 
| 1119 | 1107 | 
| 1120 bool PasswordStoreMac::AddToKeychainIfNecessary(const PasswordForm& form) { | 1108 bool PasswordStoreMac::AddToKeychainIfNecessary(const PasswordForm& form) { | 
| 1121 if (form.blacklisted_by_user) { | 1109 if (form.blacklisted_by_user) { | 
| 1122 return true; | 1110 return true; | 
| 1123 } | 1111 } | 
| 1124 MacKeychainPasswordFormAdapter keychainAdapter(keychain_.get()); | 1112 MacKeychainPasswordFormAdapter keychainAdapter(keychain_.get()); | 
| 1125 return keychainAdapter.AddPassword(form); | 1113 return keychainAdapter.AddPassword(form); | 
| 1126 } | 1114 } | 
| 1127 | 1115 | 
| 1128 bool PasswordStoreMac::DatabaseHasFormMatchingKeychainForm( | 1116 bool PasswordStoreMac::DatabaseHasFormMatchingKeychainForm( | 
| 1129 const autofill::PasswordForm& form) { | 1117 const autofill::PasswordForm& form) { | 
| 1130 DCHECK(login_metadata_db_); | 1118 DCHECK(login_metadata_db_); | 
| 1131 bool has_match = false; | 1119 bool has_match = false; | 
| 1132 std::vector<PasswordForm*> database_forms; | 1120 ScopedVector<autofill::PasswordForm> database_forms; | 
| 1133 login_metadata_db_->GetLogins(form, &database_forms); | 1121 login_metadata_db_->GetLogins(form, &database_forms); | 
| 1134 for (std::vector<PasswordForm*>::iterator i = database_forms.begin(); | 1122 for (const auto& db_form : database_forms) { | 
| 
vasilii
2015/01/27 20:45:51
a reference to the pointer
 
vabr (Chromium)
2015/01/28 13:27:35
Done.
 | |
| 1135 i != database_forms.end(); ++i) { | |
| 1136 // Below we filter out forms with non-empty original_signon_realm, because | 1123 // Below we filter out forms with non-empty original_signon_realm, because | 
| 1137 // those signal fuzzy matches, and we are only interested in exact ones. | 1124 // those signal fuzzy matches, and we are only interested in exact ones. | 
| 1138 if ((*i)->original_signon_realm.empty() && | 1125 if (db_form->original_signon_realm.empty() && | 
| 1139 internal_keychain_helpers::FormsMatchForMerge( | 1126 internal_keychain_helpers::FormsMatchForMerge( | 
| 1140 form, **i, internal_keychain_helpers::STRICT_FORM_MATCH) && | 1127 form, *db_form, internal_keychain_helpers::STRICT_FORM_MATCH) && | 
| 1141 (*i)->origin == form.origin) { | 1128 db_form->origin == form.origin) { | 
| 1142 has_match = true; | 1129 has_match = true; | 
| 1143 break; | 1130 break; | 
| 1144 } | 1131 } | 
| 1145 } | 1132 } | 
| 1146 STLDeleteElements(&database_forms); | |
| 1147 return has_match; | 1133 return has_match; | 
| 1148 } | 1134 } | 
| 1149 | 1135 | 
| 1150 void PasswordStoreMac::RemoveDatabaseForms( | 1136 void PasswordStoreMac::RemoveDatabaseForms( | 
| 1151 const std::vector<PasswordForm*>& forms) { | 1137 const std::vector<PasswordForm*>& forms) { | 
| 1152 DCHECK(login_metadata_db_); | 1138 DCHECK(login_metadata_db_); | 
| 1153 for (std::vector<PasswordForm*>::const_iterator i = forms.begin(); | 1139 for (std::vector<PasswordForm*>::const_iterator i = forms.begin(); | 
| 1154 i != forms.end(); ++i) { | 1140 i != forms.end(); ++i) { | 
| 1155 login_metadata_db_->RemoveLogin(**i); | 1141 login_metadata_db_->RemoveLogin(**i); | 
| 1156 } | 1142 } | 
| 1157 } | 1143 } | 
| 1158 | 1144 | 
| 1159 void PasswordStoreMac::RemoveKeychainForms( | 1145 void PasswordStoreMac::RemoveKeychainForms( | 
| 1160 const std::vector<PasswordForm*>& forms) { | 1146 const std::vector<PasswordForm*>& forms) { | 
| 1161 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get()); | 1147 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get()); | 
| 1162 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 1148 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 
| 1163 for (std::vector<PasswordForm*>::const_iterator i = forms.begin(); | 1149 for (std::vector<PasswordForm*>::const_iterator i = forms.begin(); | 
| 1164 i != forms.end(); ++i) { | 1150 i != forms.end(); ++i) { | 
| 1165 owned_keychain_adapter.RemovePassword(**i); | 1151 owned_keychain_adapter.RemovePassword(**i); | 
| 1166 } | 1152 } | 
| 1167 } | 1153 } | 
| 1168 | 1154 | 
| 1169 void PasswordStoreMac::CleanOrphanedForms(std::vector<PasswordForm*>* forms) { | 1155 void PasswordStoreMac::CleanOrphanedForms( | 
| 1170 DCHECK(forms); | 1156 ScopedVector<autofill::PasswordForm>* orphaned_forms) { | 
| 1157 DCHECK(orphaned_forms); | |
| 1171 DCHECK(login_metadata_db_); | 1158 DCHECK(login_metadata_db_); | 
| 1172 | 1159 | 
| 1173 std::vector<PasswordForm*> database_forms; | 1160 ScopedVector<autofill::PasswordForm> database_forms; | 
| 1174 login_metadata_db_->GetAutofillableLogins(&database_forms); | 1161 login_metadata_db_->GetAutofillableLogins(&database_forms); | 
| 1175 | 1162 | 
| 1176 ScopedVector<PasswordForm> merged_forms; | 1163 // Filter forms with corresponding Keychain entry out of |database_forms|. | 
| 1177 merged_forms.get() = internal_keychain_helpers::GetPasswordsForForms( | 1164 ScopedVector<PasswordForm> forms_with_keychain_entry; | 
| 1178 *keychain_, &database_forms); | 1165 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, | 
| 1166 &forms_with_keychain_entry); | |
| 1179 | 1167 | 
| 1180 // Clean up any orphaned database entries. | 1168 // Clean up any orphaned database entries. | 
| 1181 RemoveDatabaseForms(database_forms); | 1169 RemoveDatabaseForms(database_forms.get()); | 
| 1182 | 1170 | 
| 1183 forms->insert(forms->end(), database_forms.begin(), database_forms.end()); | 1171 // Move the orphaned DB forms to the output parameter. | 
| 1172 orphaned_forms->insert(orphaned_forms->end(), database_forms.begin(), | |
| 1173 database_forms.end()); | |
| 1174 database_forms.weak_clear(); | |
| 1184 } | 1175 } | 
| OLD | NEW |