| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/webdata/web_database.h" | 5 #include "chrome/browser/webdata/web_database.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <string> | 10 #include <string> |
| 11 | 11 |
| 12 #include "app/sql/statement.h" | 12 #include "app/sql/statement.h" |
| 13 #include "app/sql/transaction.h" | 13 #include "app/sql/transaction.h" |
| 14 #include "base/string_number_conversions.h" | 14 #include "base/string_number_conversions.h" |
| 15 #include "base/string_split.h" | 15 #include "base/string_split.h" |
| 16 #include "base/string_util.h" | 16 #include "base/string_util.h" |
| 17 #include "base/tuple.h" | 17 #include "base/tuple.h" |
| 18 #include "base/utf_string_conversions.h" | 18 #include "base/utf_string_conversions.h" |
| 19 #include "chrome/browser/autofill/autofill_country.h" |
| 19 #include "chrome/browser/autofill/autofill_profile.h" | 20 #include "chrome/browser/autofill/autofill_profile.h" |
| 20 #include "chrome/browser/autofill/autofill_type.h" | 21 #include "chrome/browser/autofill/autofill_type.h" |
| 21 #include "chrome/browser/autofill/credit_card.h" | 22 #include "chrome/browser/autofill/credit_card.h" |
| 22 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" | 23 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" |
| 23 #include "chrome/browser/history/history_database.h" | 24 #include "chrome/browser/history/history_database.h" |
| 24 #include "chrome/browser/password_manager/encryptor.h" | 25 #include "chrome/browser/password_manager/encryptor.h" |
| 25 #include "chrome/browser/search_engines/template_url.h" | 26 #include "chrome/browser/search_engines/template_url.h" |
| 26 #include "chrome/browser/webdata/autofill_change.h" | 27 #include "chrome/browser/webdata/autofill_change.h" |
| 27 #include "chrome/common/guid.h" | 28 #include "chrome/common/guid.h" |
| 28 #include "chrome/common/notification_service.h" | 29 #include "chrome/common/notification_service.h" |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 // standard entries in a contact information form. | 117 // standard entries in a contact information form. |
| 117 // | 118 // |
| 118 // guid A guid string to uniquely identify the profile. | 119 // guid A guid string to uniquely identify the profile. |
| 119 // Added in version 31. | 120 // Added in version 31. |
| 120 // company_name | 121 // company_name |
| 121 // address_line_1 | 122 // address_line_1 |
| 122 // address_line_2 | 123 // address_line_2 |
| 123 // city | 124 // city |
| 124 // state | 125 // state |
| 125 // zipcode | 126 // zipcode |
| 126 // country | 127 // country The country name. Deprecated, should be removed once |
| 128 // the stable channel reaches version 11. |
| 129 // country_code |
| 127 // date_modified The date on which this profile was last modified. | 130 // date_modified The date on which this profile was last modified. |
| 128 // Added in version 30. | 131 // Added in version 30. |
| 129 // | 132 // |
| 130 // autofill_profile_names | 133 // autofill_profile_names |
| 131 // This table contains the multi-valued name fields | 134 // This table contains the multi-valued name fields |
| 132 // associated with a profile. | 135 // associated with a profile. |
| 133 // | 136 // |
| 134 // guid The guid string that identifies the profile to which | 137 // guid The guid string that identifies the profile to which |
| 135 // the name belongs. | 138 // the name belongs. |
| 136 // first_name | 139 // first_name |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 | 185 |
| 183 using base::Time; | 186 using base::Time; |
| 184 | 187 |
| 185 namespace { | 188 namespace { |
| 186 | 189 |
| 187 typedef std::vector<Tuple3<int64, string16, string16> > AutofillElementList; | 190 typedef std::vector<Tuple3<int64, string16, string16> > AutofillElementList; |
| 188 | 191 |
| 189 // Current version number. Note: when changing the current version number, | 192 // Current version number. Note: when changing the current version number, |
| 190 // corresponding changes must happen in the unit tests, and new migration test | 193 // corresponding changes must happen in the unit tests, and new migration test |
| 191 // added. See |WebDatabaseMigrationTest::kCurrentTestedVersionNumber|. | 194 // added. See |WebDatabaseMigrationTest::kCurrentTestedVersionNumber|. |
| 192 const int kCurrentVersionNumber = 33; | 195 const int kCurrentVersionNumber = 34; |
| 193 const int kCompatibleVersionNumber = 33; | 196 const int kCompatibleVersionNumber = 34; |
| 194 | 197 |
| 195 // ID of the url column in keywords. | 198 // ID of the url column in keywords. |
| 196 const int kUrlIdPosition = 16; | 199 const int kUrlIdPosition = 16; |
| 197 | 200 |
| 198 // Keys used in the meta table. | 201 // Keys used in the meta table. |
| 199 const char* kDefaultSearchProviderKey = "Default Search Provider ID"; | 202 const char* kDefaultSearchProviderKey = "Default Search Provider ID"; |
| 200 const char* kBuiltinKeywordVersion = "Builtin Keyword Version"; | 203 const char* kBuiltinKeywordVersion = "Builtin Keyword Version"; |
| 201 | 204 |
| 202 // The maximum length allowed for form data. | 205 // The maximum length allowed for form data. |
| 203 const size_t kMaxDataLength = 1024; | 206 const size_t kMaxDataLength = 1024; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_LINE2)); | 292 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_LINE2)); |
| 290 s->BindString16(3, LimitDataSize(text)); | 293 s->BindString16(3, LimitDataSize(text)); |
| 291 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_CITY)); | 294 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_CITY)); |
| 292 s->BindString16(4, LimitDataSize(text)); | 295 s->BindString16(4, LimitDataSize(text)); |
| 293 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_STATE)); | 296 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_STATE)); |
| 294 s->BindString16(5, LimitDataSize(text)); | 297 s->BindString16(5, LimitDataSize(text)); |
| 295 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_ZIP)); | 298 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_ZIP)); |
| 296 s->BindString16(6, LimitDataSize(text)); | 299 s->BindString16(6, LimitDataSize(text)); |
| 297 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_COUNTRY)); | 300 text = profile.GetFieldText(AutoFillType(ADDRESS_HOME_COUNTRY)); |
| 298 s->BindString16(7, LimitDataSize(text)); | 301 s->BindString16(7, LimitDataSize(text)); |
| 299 s->BindInt64(8, Time::Now().ToTimeT()); | 302 std::string country_code = profile.CountryCode(); |
| 303 s->BindString(8, country_code); |
| 304 s->BindInt64(9, Time::Now().ToTimeT()); |
| 300 } | 305 } |
| 301 | 306 |
| 302 AutoFillProfile* AutoFillProfileFromStatement(const sql::Statement& s) { | 307 AutoFillProfile* AutoFillProfileFromStatement(const sql::Statement& s) { |
| 303 AutoFillProfile* profile = new AutoFillProfile; | 308 AutoFillProfile* profile = new AutoFillProfile; |
| 304 profile->set_guid(s.ColumnString(0)); | 309 profile->set_guid(s.ColumnString(0)); |
| 305 DCHECK(guid::IsValidGUID(profile->guid())); | 310 DCHECK(guid::IsValidGUID(profile->guid())); |
| 306 | 311 |
| 307 profile->SetInfo(AutoFillType(COMPANY_NAME), s.ColumnString16(1)); | 312 profile->SetInfo(AutoFillType(COMPANY_NAME), s.ColumnString16(1)); |
| 308 profile->SetInfo(AutoFillType(ADDRESS_HOME_LINE1), s.ColumnString16(2)); | 313 profile->SetInfo(AutoFillType(ADDRESS_HOME_LINE1), s.ColumnString16(2)); |
| 309 profile->SetInfo(AutoFillType(ADDRESS_HOME_LINE2), s.ColumnString16(3)); | 314 profile->SetInfo(AutoFillType(ADDRESS_HOME_LINE2), s.ColumnString16(3)); |
| 310 profile->SetInfo(AutoFillType(ADDRESS_HOME_CITY), s.ColumnString16(4)); | 315 profile->SetInfo(AutoFillType(ADDRESS_HOME_CITY), s.ColumnString16(4)); |
| 311 profile->SetInfo(AutoFillType(ADDRESS_HOME_STATE), s.ColumnString16(5)); | 316 profile->SetInfo(AutoFillType(ADDRESS_HOME_STATE), s.ColumnString16(5)); |
| 312 profile->SetInfo(AutoFillType(ADDRESS_HOME_ZIP), s.ColumnString16(6)); | 317 profile->SetInfo(AutoFillType(ADDRESS_HOME_ZIP), s.ColumnString16(6)); |
| 313 profile->SetInfo(AutoFillType(ADDRESS_HOME_COUNTRY), s.ColumnString16(7)); | 318 // Intentionally skip column 7, which stores the localized country name. |
| 314 // Intentionally skip column 8, which stores the profile's modification date. | 319 profile->SetCountryCode(s.ColumnString(8)); |
| 320 // Intentionally skip column 9, which stores the profile's modification date. |
| 315 | 321 |
| 316 return profile; | 322 return profile; |
| 317 } | 323 } |
| 318 | 324 |
| 319 void AddAutoFillProfileNameFromStatement(const sql::Statement& s, | 325 void AddAutoFillProfileNameFromStatement(const sql::Statement& s, |
| 320 AutoFillProfile* profile) { | 326 AutoFillProfile* profile) { |
| 321 DCHECK_EQ(profile->guid(), s.ColumnString(0)); | 327 DCHECK_EQ(profile->guid(), s.ColumnString(0)); |
| 322 DCHECK(guid::IsValidGUID(profile->guid())); | 328 DCHECK(guid::IsValidGUID(profile->guid())); |
| 323 | 329 |
| 324 profile->SetInfo(AutoFillType(NAME_FIRST), s.ColumnString16(1)); | 330 profile->SetInfo(AutoFillType(NAME_FIRST), s.ColumnString16(1)); |
| (...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 936 if (!db_.DoesTableExist("autofill_profiles")) { | 942 if (!db_.DoesTableExist("autofill_profiles")) { |
| 937 if (!db_.Execute("CREATE TABLE autofill_profiles ( " | 943 if (!db_.Execute("CREATE TABLE autofill_profiles ( " |
| 938 "guid VARCHAR PRIMARY KEY, " | 944 "guid VARCHAR PRIMARY KEY, " |
| 939 "company_name VARCHAR, " | 945 "company_name VARCHAR, " |
| 940 "address_line_1 VARCHAR, " | 946 "address_line_1 VARCHAR, " |
| 941 "address_line_2 VARCHAR, " | 947 "address_line_2 VARCHAR, " |
| 942 "city VARCHAR, " | 948 "city VARCHAR, " |
| 943 "state VARCHAR, " | 949 "state VARCHAR, " |
| 944 "zipcode VARCHAR, " | 950 "zipcode VARCHAR, " |
| 945 "country VARCHAR, " | 951 "country VARCHAR, " |
| 952 "country_code VARCHAR, " |
| 946 "date_modified INTEGER NOT NULL DEFAULT 0)")) { | 953 "date_modified INTEGER NOT NULL DEFAULT 0)")) { |
| 947 NOTREACHED(); | 954 NOTREACHED(); |
| 948 return false; | 955 return false; |
| 949 } | 956 } |
| 950 } | 957 } |
| 951 return true; | 958 return true; |
| 952 } | 959 } |
| 953 | 960 |
| 954 bool WebDatabase::InitAutoFillProfileNamesTable() { | 961 bool WebDatabase::InitAutoFillProfileNamesTable() { |
| 955 if (!db_.DoesTableExist("autofill_profile_names")) { | 962 if (!db_.DoesTableExist("autofill_profile_names")) { |
| (...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1836 | 1843 |
| 1837 if (s.Step()) | 1844 if (s.Step()) |
| 1838 return RemoveFormElementForID(s.ColumnInt64(0)); | 1845 return RemoveFormElementForID(s.ColumnInt64(0)); |
| 1839 return false; | 1846 return false; |
| 1840 } | 1847 } |
| 1841 | 1848 |
| 1842 bool WebDatabase::AddAutoFillProfile(const AutoFillProfile& profile) { | 1849 bool WebDatabase::AddAutoFillProfile(const AutoFillProfile& profile) { |
| 1843 sql::Statement s(db_.GetUniqueStatement( | 1850 sql::Statement s(db_.GetUniqueStatement( |
| 1844 "INSERT INTO autofill_profiles" | 1851 "INSERT INTO autofill_profiles" |
| 1845 "(guid, company_name, address_line_1, address_line_2, city, state," | 1852 "(guid, company_name, address_line_1, address_line_2, city, state," |
| 1846 " zipcode, country, date_modified)" | 1853 " zipcode, country, country_code, date_modified)" |
| 1847 "VALUES (?,?,?,?,?,?,?,?,?)")); | 1854 "VALUES (?,?,?,?,?,?,?,?,?,?)")); |
| 1848 if (!s) { | 1855 if (!s) { |
| 1849 NOTREACHED() << "Statement prepare failed"; | 1856 NOTREACHED() << "Statement prepare failed"; |
| 1850 return false; | 1857 return false; |
| 1851 } | 1858 } |
| 1852 | 1859 |
| 1853 BindAutoFillProfileToStatement(profile, &s); | 1860 BindAutoFillProfileToStatement(profile, &s); |
| 1854 | 1861 |
| 1855 if (!s.Run()) { | 1862 if (!s.Run()) { |
| 1856 NOTREACHED(); | 1863 NOTREACHED(); |
| 1857 return false; | 1864 return false; |
| 1858 } | 1865 } |
| 1859 | 1866 |
| 1860 if (!s.Succeeded()) | 1867 if (!s.Succeeded()) |
| 1861 return false; | 1868 return false; |
| 1862 | 1869 |
| 1863 return AddAutoFillProfilePieces(profile.guid(), profile, &db_); | 1870 return AddAutoFillProfilePieces(profile.guid(), profile, &db_); |
| 1864 } | 1871 } |
| 1865 | 1872 |
| 1866 bool WebDatabase::GetAutoFillProfile(const std::string& guid, | 1873 bool WebDatabase::GetAutoFillProfile(const std::string& guid, |
| 1867 AutoFillProfile** profile) { | 1874 AutoFillProfile** profile) { |
| 1868 DCHECK(guid::IsValidGUID(guid)); | 1875 DCHECK(guid::IsValidGUID(guid)); |
| 1869 DCHECK(profile); | 1876 DCHECK(profile); |
| 1870 sql::Statement s(db_.GetUniqueStatement( | 1877 sql::Statement s(db_.GetUniqueStatement( |
| 1871 "SELECT guid, company_name, address_line_1, address_line_2, city, state," | 1878 "SELECT guid, company_name, address_line_1, address_line_2, city, state," |
| 1872 " zipcode, country, date_modified " | 1879 " zipcode, country, country_code, date_modified " |
| 1873 "FROM autofill_profiles " | 1880 "FROM autofill_profiles " |
| 1874 "WHERE guid=?")); | 1881 "WHERE guid=?")); |
| 1875 if (!s) { | 1882 if (!s) { |
| 1876 NOTREACHED() << "Statement prepare failed"; | 1883 NOTREACHED() << "Statement prepare failed"; |
| 1877 return false; | 1884 return false; |
| 1878 } | 1885 } |
| 1879 | 1886 |
| 1880 s.BindString(0, guid); | 1887 s.BindString(0, guid); |
| 1881 if (!s.Step()) | 1888 if (!s.Step()) |
| 1882 return false; | 1889 return false; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1984 return false; | 1991 return false; |
| 1985 | 1992 |
| 1986 // Preserve appropriate modification dates by not updating unchanged profiles. | 1993 // Preserve appropriate modification dates by not updating unchanged profiles. |
| 1987 scoped_ptr<AutoFillProfile> old_profile(tmp_profile); | 1994 scoped_ptr<AutoFillProfile> old_profile(tmp_profile); |
| 1988 if (*old_profile == profile) | 1995 if (*old_profile == profile) |
| 1989 return true; | 1996 return true; |
| 1990 | 1997 |
| 1991 sql::Statement s(db_.GetUniqueStatement( | 1998 sql::Statement s(db_.GetUniqueStatement( |
| 1992 "UPDATE autofill_profiles " | 1999 "UPDATE autofill_profiles " |
| 1993 "SET guid=?, company_name=?, address_line_1=?, address_line_2=?, " | 2000 "SET guid=?, company_name=?, address_line_1=?, address_line_2=?, " |
| 1994 " city=?, state=?, zipcode=?, country=?, date_modified=? " | 2001 " city=?, state=?, zipcode=?, country=?, country_code=?, " |
| 2002 " date_modified=? " |
| 1995 "WHERE guid=?")); | 2003 "WHERE guid=?")); |
| 1996 if (!s) { | 2004 if (!s) { |
| 1997 NOTREACHED() << "Statement prepare failed"; | 2005 NOTREACHED() << "Statement prepare failed"; |
| 1998 return false; | 2006 return false; |
| 1999 } | 2007 } |
| 2000 | 2008 |
| 2001 BindAutoFillProfileToStatement(profile, &s); | 2009 BindAutoFillProfileToStatement(profile, &s); |
| 2002 s.BindString(9, profile.guid()); | 2010 s.BindString(10, profile.guid()); |
| 2003 bool result = s.Run(); | 2011 bool result = s.Run(); |
| 2004 DCHECK_GT(db_.GetLastChangeCount(), 0); | 2012 DCHECK_GT(db_.GetLastChangeCount(), 0); |
| 2005 if (!result) | 2013 if (!result) |
| 2006 return result; | 2014 return result; |
| 2007 | 2015 |
| 2008 // Remove the old names, emails, and phone/fax numbers. | 2016 // Remove the old names, emails, and phone/fax numbers. |
| 2009 if (!RemoveAutoFillProfilePieces(profile.guid(), &db_)) | 2017 if (!RemoveAutoFillProfilePieces(profile.guid(), &db_)) |
| 2010 return false; | 2018 return false; |
| 2011 | 2019 |
| 2012 return AddAutoFillProfilePieces(profile.guid(), profile, &db_); | 2020 return AddAutoFillProfilePieces(profile.guid(), profile, &db_); |
| (...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3001 return sql::INIT_FAILURE; | 3009 return sql::INIT_FAILURE; |
| 3002 } | 3010 } |
| 3003 } | 3011 } |
| 3004 | 3012 |
| 3005 meta_table_.SetVersionNumber(33); | 3013 meta_table_.SetVersionNumber(33); |
| 3006 meta_table_.SetCompatibleVersionNumber( | 3014 meta_table_.SetCompatibleVersionNumber( |
| 3007 std::min(33, kCompatibleVersionNumber)); | 3015 std::min(33, kCompatibleVersionNumber)); |
| 3008 | 3016 |
| 3009 // FALL THROUGH | 3017 // FALL THROUGH |
| 3010 | 3018 |
| 3019 case 33: |
| 3020 // Test the existence of the |country_code| column as an indication that |
| 3021 // we need a migration. It is possible that the new |autofill_profiles| |
| 3022 // schema is in place because the table was newly created when migrating |
| 3023 // from a pre-version-22 database. |
| 3024 if (!db_.DoesColumnExist("autofill_profiles", "country_code")) { |
| 3025 if (!db_.Execute("ALTER TABLE autofill_profiles ADD COLUMN " |
| 3026 "country_code VARCHAR")) { |
| 3027 LOG(WARNING) << "Unable to update web database to version 33."; |
| 3028 NOTREACHED(); |
| 3029 return sql::INIT_FAILURE; |
| 3030 } |
| 3031 |
| 3032 // Set all the |country_code| fields to match existing |country| values. |
| 3033 { |
| 3034 sql::Statement s(db_.GetUniqueStatement("SELECT guid, country " |
| 3035 "FROM autofill_profiles")); |
| 3036 |
| 3037 if (!s) { |
| 3038 LOG(WARNING) << "Unable to update web database to version 33."; |
| 3039 NOTREACHED(); |
| 3040 return sql::INIT_FAILURE; |
| 3041 } |
| 3042 |
| 3043 while (s.Step()) { |
| 3044 sql::Statement update_s( |
| 3045 db_.GetUniqueStatement("UPDATE autofill_profiles " |
| 3046 "SET country_code=? WHERE guid=?")); |
| 3047 if (!update_s) { |
| 3048 LOG(WARNING) << "Unable to update web database to version 33."; |
| 3049 NOTREACHED(); |
| 3050 return sql::INIT_FAILURE; |
| 3051 } |
| 3052 string16 country = s.ColumnString16(1); |
| 3053 std::string app_locale = AutoFillCountry::ApplicationLocale(); |
| 3054 update_s.BindString(0, AutoFillCountry::GetCountryCode(country, |
| 3055 app_locale)); |
| 3056 update_s.BindString(1, s.ColumnString(0)); |
| 3057 |
| 3058 if (!update_s.Run()) { |
| 3059 LOG(WARNING) << "Unable to update web database to version 33."; |
| 3060 NOTREACHED(); |
| 3061 return sql::INIT_FAILURE; |
| 3062 } |
| 3063 } |
| 3064 } |
| 3065 } |
| 3066 |
| 3067 meta_table_.SetVersionNumber(34); |
| 3068 meta_table_.SetCompatibleVersionNumber( |
| 3069 std::min(34, kCompatibleVersionNumber)); |
| 3070 |
| 3071 // FALL THROUGH |
| 3072 |
| 3011 // Add successive versions here. Each should set the version number and | 3073 // Add successive versions here. Each should set the version number and |
| 3012 // compatible version number as appropriate, then fall through to the next | 3074 // compatible version number as appropriate, then fall through to the next |
| 3013 // case. | 3075 // case. |
| 3014 | 3076 |
| 3015 case kCurrentVersionNumber: | 3077 case kCurrentVersionNumber: |
| 3016 // No migration needed. | 3078 // No migration needed. |
| 3017 return sql::INIT_OK; | 3079 return sql::INIT_OK; |
| 3018 } | 3080 } |
| 3019 } | 3081 } |
| OLD | NEW |