Index: components/password_manager/core/browser/login_database.cc |
diff --git a/components/password_manager/core/browser/login_database.cc b/components/password_manager/core/browser/login_database.cc |
index ff7d4da279494411702d1a367111191618c5bbc3..cf64f529c9ee4210170ec5e8dc9c562a584f2392 100644 |
--- a/components/password_manager/core/browser/login_database.cc |
+++ b/components/password_manager/core/browser/login_database.cc |
@@ -44,26 +44,31 @@ using autofill::PasswordForm; |
namespace password_manager { |
// The current version number of the login database schema. |
-const int kCurrentVersionNumber = 18; |
+const int kCurrentVersionNumber = 19; |
// The oldest version of the schema such that a legacy Chrome client using that |
// version can still read/write the current database. |
-const int kCompatibleVersionNumber = 18; |
+const int kCompatibleVersionNumber = 19; |
-base::Pickle SerializeVector(const std::vector<base::string16>& vec) { |
+base::Pickle SerializePossibleUsernamePairs( |
+ const autofill::PossibleUsernamesVector& vec) { |
base::Pickle p; |
for (size_t i = 0; i < vec.size(); ++i) { |
- p.WriteString16(vec[i]); |
+ p.WriteString16(vec[i].first); |
+ p.WriteString16(vec[i].second); |
} |
return p; |
} |
-std::vector<base::string16> DeserializeVector(const base::Pickle& p) { |
- std::vector<base::string16> ret; |
- base::string16 str; |
+autofill::PossibleUsernamesVector DeserializePossibleUsernamePairs( |
+ const base::Pickle& p) { |
+ autofill::PossibleUsernamesVector ret; |
+ base::string16 value; |
+ base::string16 field_name; |
base::PickleIterator iterator(p); |
- while (iterator.ReadString16(&str)) { |
- ret.push_back(str); |
+ while (iterator.ReadString16(&value)) { |
+ DCHECK(iterator.ReadString16(&field_name)); |
vabr (Chromium)
2017/03/16 21:00:42
Don't push the ReadString16 into a DCHECK! This wo
kolos1
2017/03/17 14:09:34
ah, of course.
I though the release compiler wou
|
+ ret.push_back(autofill::PossibleUsernamePair(value, field_name)); |
} |
return ret; |
} |
@@ -85,7 +90,6 @@ enum LoginTableColumns { |
COLUMN_BLACKLISTED_BY_USER, |
COLUMN_SCHEME, |
COLUMN_PASSWORD_TYPE, |
- COLUMN_POSSIBLE_USERNAMES, |
COLUMN_TIMES_USED, |
COLUMN_FORM_DATA, |
COLUMN_DATE_SYNCED, |
@@ -94,6 +98,7 @@ enum LoginTableColumns { |
COLUMN_FEDERATION_URL, |
COLUMN_SKIP_ZERO_CLICK, |
COLUMN_GENERATION_UPLOAD_STATUS, |
+ COLUMN_POSSIBLE_USERNAME_PAIRS, |
COLUMN_NUM // Keep this last. |
}; |
@@ -131,11 +136,6 @@ void BindAddStatement(const PasswordForm& form, |
s->BindInt(COLUMN_BLACKLISTED_BY_USER, form.blacklisted_by_user); |
s->BindInt(COLUMN_SCHEME, form.scheme); |
s->BindInt(COLUMN_PASSWORD_TYPE, form.type); |
- base::Pickle usernames_pickle = |
- SerializeVector(form.other_possible_usernames); |
- s->BindBlob(COLUMN_POSSIBLE_USERNAMES, |
- usernames_pickle.data(), |
- usernames_pickle.size()); |
s->BindInt(COLUMN_TIMES_USED, form.times_used); |
base::Pickle form_data_pickle; |
autofill::SerializeFormData(form.form_data, &form_data_pickle); |
@@ -152,6 +152,10 @@ void BindAddStatement(const PasswordForm& form, |
: form.federation_origin.Serialize()); |
s->BindInt(COLUMN_SKIP_ZERO_CLICK, form.skip_zero_click); |
s->BindInt(COLUMN_GENERATION_UPLOAD_STATUS, form.generation_upload_status); |
+ base::Pickle usernames_pickle = |
+ SerializePossibleUsernamePairs(form.other_possible_usernames); |
+ s->BindBlob(COLUMN_POSSIBLE_USERNAME_PAIRS, usernames_pickle.data(), |
+ usernames_pickle.size()); |
} |
void AddCallback(int err, sql::Statement* /*stmt*/) { |
@@ -431,6 +435,12 @@ void InitializeBuilder(SQLTableBuilder* builder) { |
version = builder->SealVersion(); |
DCHECK_EQ(18u, version); |
+ // Version 19. |
+ builder->DropColumn("possible_usernames"); |
+ builder->AddColumn("possible_username_pairs", "BLOB"); |
+ version = builder->SealVersion(); |
+ DCHECK_EQ(19u, version); |
+ |
DCHECK_EQ(static_cast<size_t>(COLUMN_NUM), builder->NumberOfColumns()) |
<< "Adjust LoginTableColumns if you change column definitions here."; |
} |
@@ -844,37 +854,43 @@ PasswordStoreChangeList LoginDatabase::UpdateLogin(const PasswordForm& form) { |
DCHECK(!update_statement_.empty()); |
sql::Statement s( |
db_.GetCachedStatement(SQL_FROM_HERE, update_statement_.c_str())); |
- s.BindString(0, form.action.spec()); |
- s.BindBlob(1, encrypted_password.data(), |
+ int next_param = 0; |
+ s.BindString(next_param++, form.action.spec()); |
+ s.BindBlob(next_param++, encrypted_password.data(), |
static_cast<int>(encrypted_password.length())); |
- s.BindString16(2, form.submit_element); |
- s.BindInt(3, form.preferred); |
- s.BindInt64(4, form.date_created.ToInternalValue()); |
- s.BindInt(5, form.blacklisted_by_user); |
- s.BindInt(6, form.scheme); |
- s.BindInt(7, form.type); |
- base::Pickle pickle = SerializeVector(form.other_possible_usernames); |
- s.BindBlob(8, pickle.data(), pickle.size()); |
- s.BindInt(9, form.times_used); |
+ s.BindString16(next_param++, form.submit_element); |
+ s.BindInt(next_param++, form.preferred); |
+ s.BindInt64(next_param++, form.date_created.ToInternalValue()); |
+ s.BindInt(next_param++, form.blacklisted_by_user); |
+ s.BindInt(next_param++, form.scheme); |
+ s.BindInt(next_param++, form.type); |
+ s.BindInt(next_param++, form.times_used); |
base::Pickle form_data_pickle; |
autofill::SerializeFormData(form.form_data, &form_data_pickle); |
- s.BindBlob(10, form_data_pickle.data(), form_data_pickle.size()); |
- s.BindInt64(11, form.date_synced.ToInternalValue()); |
- s.BindString16(12, form.display_name); |
- s.BindString(13, form.icon_url.spec()); |
+ s.BindBlob(next_param++, form_data_pickle.data(), form_data_pickle.size()); |
+ s.BindInt64(next_param++, form.date_synced.ToInternalValue()); |
+ s.BindString16(next_param++, form.display_name); |
+ s.BindString(next_param++, form.icon_url.spec()); |
// An empty Origin serializes as "null" which would be strange to store here. |
- s.BindString(14, form.federation_origin.unique() |
- ? std::string() |
- : form.federation_origin.Serialize()); |
- s.BindInt(15, form.skip_zero_click); |
- s.BindInt(16, form.generation_upload_status); |
+ s.BindString(next_param++, form.federation_origin.unique() |
+ ? std::string() |
+ : form.federation_origin.Serialize()); |
+ s.BindInt(next_param++, form.skip_zero_click); |
+ s.BindInt(next_param++, form.generation_upload_status); |
+ base::Pickle username_pickle = |
+ SerializePossibleUsernamePairs(form.other_possible_usernames); |
+ s.BindBlob(next_param++, username_pickle.data(), username_pickle.size()); |
+ // NOTE: Add new fields here unless the field is a part of the unique key. |
+ // If so, add new field below. |
// WHERE starts here. |
- s.BindString(17, form.origin.spec()); |
- s.BindString16(18, form.username_element); |
- s.BindString16(19, form.username_value); |
- s.BindString16(20, form.password_element); |
- s.BindString(21, form.signon_realm); |
+ s.BindString(next_param++, form.origin.spec()); |
+ s.BindString16(next_param++, form.username_element); |
+ s.BindString16(next_param++, form.username_value); |
+ s.BindString16(next_param++, form.password_element); |
+ s.BindString(next_param++, form.signon_realm); |
+ // NOTE: Add new fields here only if the field is a part of the unique key. |
+ // Otherwise, add the field above "WHERE starts here" comment. |
if (!s.Run()) |
return PasswordStoreChangeList(); |
@@ -998,11 +1014,11 @@ LoginDatabase::EncryptionResult LoginDatabase::InitPasswordFormFromStatement( |
int type_int = s.ColumnInt(COLUMN_PASSWORD_TYPE); |
DCHECK(type_int >= 0 && type_int <= PasswordForm::TYPE_LAST) << type_int; |
form->type = static_cast<PasswordForm::Type>(type_int); |
- if (s.ColumnByteLength(COLUMN_POSSIBLE_USERNAMES)) { |
+ if (s.ColumnByteLength(COLUMN_POSSIBLE_USERNAME_PAIRS)) { |
base::Pickle pickle( |
- static_cast<const char*>(s.ColumnBlob(COLUMN_POSSIBLE_USERNAMES)), |
- s.ColumnByteLength(COLUMN_POSSIBLE_USERNAMES)); |
- form->other_possible_usernames = DeserializeVector(pickle); |
+ static_cast<const char*>(s.ColumnBlob(COLUMN_POSSIBLE_USERNAME_PAIRS)), |
+ s.ColumnByteLength(COLUMN_POSSIBLE_USERNAME_PAIRS)); |
+ form->other_possible_usernames = DeserializePossibleUsernamePairs(pickle); |
} |
form->times_used = s.ColumnInt(COLUMN_TIMES_USED); |
if (s.ColumnByteLength(COLUMN_FORM_DATA)) { |