Index: chrome/browser/password_manager/password_store_mac.cc |
diff --git a/chrome/browser/password_manager/password_store_mac.cc b/chrome/browser/password_manager/password_store_mac.cc |
index 1804386196c7643508834d84ff46b4ccc0cba902..2b26c5a8b27d49accf3274ee873f3d53b1dd38db 100644 |
--- a/chrome/browser/password_manager/password_store_mac.cc |
+++ b/chrome/browser/password_manager/password_store_mac.cc |
@@ -504,6 +504,20 @@ PasswordForm* MacKeychainPasswordFormAdapter::PasswordExactlyMatchingForm( |
return NULL; |
} |
+bool MacKeychainPasswordFormAdapter::HasPasswordsMergeableWithForm( |
+ const PasswordForm& query_form) { |
+ std::string username = UTF16ToUTF8(query_form.username_value); |
+ std::vector<SecKeychainItemRef> matches = |
+ MatchingKeychainItems(query_form.signon_realm, query_form.scheme, |
+ NULL, username.c_str()); |
+ for (std::vector<SecKeychainItemRef>::iterator i = matches.begin(); |
+ i != matches.end(); ++i) { |
+ keychain_->Free(*i); |
+ } |
+ |
+ return matches.size() != 0; |
+} |
+ |
std::vector<PasswordForm*> |
MacKeychainPasswordFormAdapter::GetAllPasswordFormPasswords() { |
SecAuthenticationType supported_auth_types[] = { |
@@ -762,30 +776,36 @@ void PasswordStoreMac::AddLoginImpl(const PasswordForm& form) { |
} |
void PasswordStoreMac::UpdateLoginImpl(const PasswordForm& form) { |
+ int update_count = 0; |
+ if (!login_metadata_db_->UpdateLogin(form, &update_count)) |
+ return; |
+ |
+ MacKeychainPasswordFormAdapter keychain_adapter(keychain_.get()); |
+ if (update_count == 0 && |
+ !keychain_adapter.HasPasswordsMergeableWithForm(form)) { |
+ // If the password isn't in either the DB or the keychain, then it must have |
+ // been deleted after autofill happened, and should not be re-added. |
+ return; |
+ } |
+ |
// The keychain add will update if there is a collision and add if there |
// isn't, which is the behavior we want, so there's no separate update call. |
if (AddToKeychainIfNecessary(form)) { |
- int update_count = 0; |
- if (login_metadata_db_->UpdateLogin(form, &update_count)) { |
- // Update will catch any database entries that we already had, but we |
- // could also be updating a keychain-only form, in which case we need to |
- // add. |
- PasswordStoreChangeList changes; |
- if (update_count == 0) { |
- if (login_metadata_db_->AddLogin(form)) { |
- changes.push_back(PasswordStoreChange(PasswordStoreChange::ADD, |
- form)); |
- } |
- } else { |
- changes.push_back(PasswordStoreChange(PasswordStoreChange::UPDATE, |
+ PasswordStoreChangeList changes; |
+ if (update_count == 0) { |
+ if (login_metadata_db_->AddLogin(form)) { |
+ changes.push_back(PasswordStoreChange(PasswordStoreChange::ADD, |
form)); |
} |
- if (!changes.empty()) { |
- NotificationService::current()->Notify( |
- NotificationType::LOGINS_CHANGED, |
- NotificationService::AllSources(), |
- Details<PasswordStoreChangeList>(&changes)); |
- } |
+ } else { |
+ changes.push_back(PasswordStoreChange(PasswordStoreChange::UPDATE, |
+ form)); |
+ } |
+ if (!changes.empty()) { |
+ NotificationService::current()->Notify( |
+ NotificationType::LOGINS_CHANGED, |
+ NotificationService::AllSources(), |
+ Details<PasswordStoreChangeList>(&changes)); |
} |
} |
} |