summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/webdata/autofill_change.cc9
-rw-r--r--chrome/browser/webdata/autofill_change.h4
-rw-r--r--chrome/browser/webdata/autofill_entry.cc9
-rw-r--r--chrome/browser/webdata/autofill_entry.h4
-rw-r--r--chrome/browser/webdata/web_data_service.cc4
-rw-r--r--chrome/browser/webdata/web_database.cc63
-rw-r--r--chrome/browser/webdata/web_database.h28
-rw-r--r--chrome/browser/webdata/web_database_unittest.cc104
8 files changed, 186 insertions, 39 deletions
diff --git a/chrome/browser/webdata/autofill_change.cc b/chrome/browser/webdata/autofill_change.cc
new file mode 100644
index 0000000..ceb8205
--- /dev/null
+++ b/chrome/browser/webdata/autofill_change.cc
@@ -0,0 +1,9 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/webdata/autofill_change.h"
+
+bool AutofillChange::operator==(const AutofillChange& change) const {
+ return type_ == change.type() && key_ == change.key();
+}
diff --git a/chrome/browser/webdata/autofill_change.h b/chrome/browser/webdata/autofill_change.h
index 2eb8d50..ea16846 100644
--- a/chrome/browser/webdata/autofill_change.h
+++ b/chrome/browser/webdata/autofill_change.h
@@ -23,9 +23,7 @@ class AutofillChange {
Type type() const { return type_; }
const AutofillKey& key() const { return key_; }
- bool operator==(const AutofillChange& change) const {
- return type_ == change.type() && key_ == change.key();
- }
+ bool operator==(const AutofillChange& change) const;
private:
Type type_;
diff --git a/chrome/browser/webdata/autofill_entry.cc b/chrome/browser/webdata/autofill_entry.cc
new file mode 100644
index 0000000..7e0b106
--- /dev/null
+++ b/chrome/browser/webdata/autofill_entry.cc
@@ -0,0 +1,9 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/webdata/autofill_entry.h"
+
+bool AutofillKey::operator==(const AutofillKey& key) const {
+ return name_ == key.name() && value_ == key.value();
+}
diff --git a/chrome/browser/webdata/autofill_entry.h b/chrome/browser/webdata/autofill_entry.h
index 9aadc3a..664cbaeb 100644
--- a/chrome/browser/webdata/autofill_entry.h
+++ b/chrome/browser/webdata/autofill_entry.h
@@ -20,9 +20,7 @@ class AutofillKey {
const string16& name() const { return name_; }
const string16& value() const { return value_; }
- bool operator==(const AutofillKey& key) const {
- return name_ == key.name() && value_ == key.value();
- }
+ bool operator==(const AutofillKey& key) const;
private:
string16 name_;
diff --git a/chrome/browser/webdata/web_data_service.cc b/chrome/browser/webdata/web_data_service.cc
index ee1d4c9..1b81ac2 100644
--- a/chrome/browser/webdata/web_data_service.cc
+++ b/chrome/browser/webdata/web_data_service.cc
@@ -652,8 +652,10 @@ void WebDataService::RemoveFormElementsAddedBetweenImpl(
GenericRequest2<Time, Time>* request) {
InitializeDatabaseIfNecessary();
if (db_ && !request->IsCancelled()) {
+ AutofillChangeList changes;
if (db_->RemoveFormElementsAddedBetween(request->GetArgument1(),
- request->GetArgument2()))
+ request->GetArgument2(),
+ &changes))
ScheduleCommit();
}
request->RequestComplete();
diff --git a/chrome/browser/webdata/web_database.cc b/chrome/browser/webdata/web_database.cc
index b20ca2c..41d5e8b 100644
--- a/chrome/browser/webdata/web_database.cc
+++ b/chrome/browser/webdata/web_database.cc
@@ -10,9 +10,11 @@
#include "app/l10n_util.h"
#include "app/sql/statement.h"
#include "app/sql/transaction.h"
+#include "base/tuple.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/diagnostics/sqlite_diagnostics.h"
#include "chrome/browser/history/history_database.h"
+#include "chrome/browser/webdata/autofill_change.h"
#include "webkit/glue/password_form.h"
// Encryptor is the *wrong* way of doing things; we need to turn it into a
@@ -116,6 +118,10 @@ std::string JoinStrings(const std::string& separator,
return result;
}
+namespace {
+typedef std::vector<Tuple3<int64, string16, string16> > AutofillElementList;
+}
+
WebDatabase::WebDatabase() {
}
@@ -798,14 +804,18 @@ bool WebDatabase::GetAllLogins(std::vector<PasswordForm*>* forms,
return s.Succeeded();
}
-bool WebDatabase::AddFormFieldValues(
- const std::vector<FormField>& elements) {
+bool WebDatabase::AddFormFieldValues(const std::vector<FormField>& elements) {
+ return AddFormFieldValuesTime(elements, Time::Now());
+}
+
+bool WebDatabase::AddFormFieldValuesTime(const std::vector<FormField>& elements,
+ base::Time time) {
bool result = true;
for (std::vector<FormField>::const_iterator
itr = elements.begin();
itr != elements.end();
itr++) {
- result = result && AddFormFieldValue(*itr);
+ result = result && AddFormFieldValueTime(*itr, time);
}
return result;
}
@@ -936,6 +946,11 @@ bool WebDatabase::SetCountOfFormElement(int64 pair_id, int count) {
}
bool WebDatabase::AddFormFieldValue(const FormField& element) {
+ return AddFormFieldValueTime(element, base::Time::Now());
+}
+
+bool WebDatabase::AddFormFieldValueTime(const FormField& element,
+ base::Time time) {
int count = 0;
int64 pair_id;
@@ -946,7 +961,7 @@ bool WebDatabase::AddFormFieldValue(const FormField& element) {
return false;
return SetCountOfFormElement(pair_id, count + 1) &&
- InsertPairIDAndDate(pair_id, Time::Now());
+ InsertPairIDAndDate(pair_id, time);
}
bool WebDatabase::GetFormValuesForElementName(const string16& name,
@@ -998,11 +1013,17 @@ bool WebDatabase::GetFormValuesForElementName(const string16& name,
return s.Succeeded();
}
-bool WebDatabase::RemoveFormElementsAddedBetween(base::Time delete_begin,
- base::Time delete_end) {
+bool WebDatabase::RemoveFormElementsAddedBetween(
+ base::Time delete_begin,
+ base::Time delete_end,
+ std::vector<AutofillChange>* changes) {
+ DCHECK(changes);
+ // Query for the pair_id, name, and value of all form elements that
+ // were used between the given times.
sql::Statement s(db_.GetUniqueStatement(
- "SELECT DISTINCT pair_id FROM autofill_dates "
- "WHERE date_created >= ? AND date_created < ?"));
+ "SELECT DISTINCT a.pair_id, a.name, a.value "
+ "FROM autofill_dates ad JOIN autofill a ON ad.pair_id = a.pair_id "
+ "WHERE ad.date_created >= ? AND ad.date_created < ?"));
if (!s) {
NOTREACHED() << "Statement 1 prepare failed";
return false;
@@ -1013,25 +1034,32 @@ bool WebDatabase::RemoveFormElementsAddedBetween(base::Time delete_begin,
std::numeric_limits<int64>::max() :
delete_end.ToTimeT());
- std::vector<int64> pair_ids;
+ AutofillElementList elements;
while (s.Step())
- pair_ids.push_back(s.ColumnInt64(0));
+ elements.push_back(MakeTuple(s.ColumnInt64(0),
+ UTF8ToUTF16(s.ColumnString(1)),
+ UTF8ToUTF16(s.ColumnString(2))));
if (!s.Succeeded()) {
NOTREACHED();
return false;
}
- for (std::vector<int64>::iterator itr = pair_ids.begin();
- itr != pair_ids.end();
+ for (AutofillElementList::iterator itr = elements.begin();
+ itr != elements.end();
itr++) {
int how_many = 0;
- if (!RemoveFormElementForTimeRange(*itr, delete_begin, delete_end,
+ if (!RemoveFormElementForTimeRange(itr->a, delete_begin, delete_end,
&how_many)) {
return false;
}
- if (!AddToCountOfFormElement(*itr, -how_many))
+ bool was_removed = false;
+ if (!AddToCountOfFormElement(itr->a, -how_many, &was_removed))
return false;
+ AutofillChange::Type change_type =
+ was_removed ? AutofillChange::REMOVE : AutofillChange::UPDATE;
+ changes->push_back(AutofillChange(change_type,
+ AutofillKey(itr->b, itr->c)));
}
return true;
@@ -1077,8 +1105,12 @@ bool WebDatabase::RemoveFormElement(const string16& name,
return false;
}
-bool WebDatabase::AddToCountOfFormElement(int64 pair_id, int delta) {
+bool WebDatabase::AddToCountOfFormElement(int64 pair_id,
+ int delta,
+ bool* was_removed) {
+ DCHECK(was_removed);
int count = 0;
+ *was_removed = false;
if (!GetCountOfFormElement(pair_id, &count))
return false;
@@ -1086,6 +1118,7 @@ bool WebDatabase::AddToCountOfFormElement(int64 pair_id, int delta) {
if (count + delta == 0) {
if (!RemoveFormElementForID(pair_id))
return false;
+ *was_removed = true;
} else {
if (!SetCountOfFormElement(pair_id, count + delta))
return false;
diff --git a/chrome/browser/webdata/web_database.h b/chrome/browser/webdata/web_database.h
index 8d93363..f5451ab 100644
--- a/chrome/browser/webdata/web_database.h
+++ b/chrome/browser/webdata/web_database.h
@@ -14,6 +14,7 @@
#include "testing/gtest/include/gtest/gtest_prod.h"
#include "webkit/glue/form_field.h"
+class AutofillChange;
class FilePath;
namespace base {
@@ -144,11 +145,14 @@ class WebDatabase {
int limit);
// Removes rows from autofill_dates if they were created on or after
- // |delete_begin| and strictly before |delete_end|. Decrements the count of
- // the corresponding rows in the autofill table, and removes those rows if the
- // count goes to 0.
+ // |delete_begin| and strictly before |delete_end|. Decrements the
+ // count of the corresponding rows in the autofill table, and
+ // removes those rows if the count goes to 0. A list of all changed
+ // keys and whether each was updater or removed is returned in the
+ // changes out parameter.
bool RemoveFormElementsAddedBetween(base::Time delete_begin,
- base::Time delete_end);
+ base::Time delete_end,
+ std::vector<AutofillChange>* changes);
// Removes from autofill_dates rows with given pair_id where date_created lies
// between delte_begin and delte_end.
@@ -157,9 +161,10 @@ class WebDatabase {
base::Time delete_end,
int* how_many);
- // Increments the count in the row corresponding to |pair_id| by |delta|.
- // Removes the row from the table if the count becomes 0.
- bool AddToCountOfFormElement(int64 pair_id, int delta);
+ // Increments the count in the row corresponding to |pair_id| by
+ // |delta|. Removes the row from the table and sets the
+ // |was_removed| out parameter to true if the count becomes 0.
+ bool AddToCountOfFormElement(int64 pair_id, int delta, bool* was_removed);
// Gets the pair_id and count entries from name and value specified in
// |element|. Sets *count to 0 if there is no such row in the table.
@@ -202,6 +207,15 @@ class WebDatabase {
private:
FRIEND_TEST(WebDatabaseTest, Autofill);
+ FRIEND_TEST(WebDatabaseTest, Autofill_RemoveBetweenChanges);
+
+ // Methods for adding autofill entries at a specified time. For
+ // testing only.
+ bool AddFormFieldValuesTime(
+ const std::vector<webkit_glue::FormField>& elements,
+ base::Time time);
+ bool AddFormFieldValueTime(const webkit_glue::FormField& element,
+ base::Time time);
// Removes empty values for autofill that were incorrectly stored in the DB
// (see bug http://crbug.com/6111).
diff --git a/chrome/browser/webdata/web_database_unittest.cc b/chrome/browser/webdata/web_database_unittest.cc
index beb716d..eb94e4f 100644
--- a/chrome/browser/webdata/web_database_unittest.cc
+++ b/chrome/browser/webdata/web_database_unittest.cc
@@ -9,6 +9,8 @@
#include "base/time.h"
#include "base/values.h"
#include "chrome/browser/search_engines/template_url.h"
+#include "chrome/browser/webdata/autofill_change.h"
+#include "chrome/browser/webdata/autofill_entry.h"
#include "chrome/browser/webdata/web_database.h"
#include "chrome/common/chrome_paths.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -21,6 +23,30 @@ using base::TimeDelta;
using webkit_glue::FormField;
using webkit_glue::PasswordForm;
+// So we can compare AutofillKeys with EXPECT_EQ().
+std::ostream& operator<<(std::ostream& os, const AutofillKey& key) {
+ return os << UTF16ToASCII(key.name()) << ", " << UTF16ToASCII(key.value());
+}
+
+// So we can compare AutofillChanges with EXPECT_EQ().
+std::ostream& operator<<(std::ostream& os, const AutofillChange& change) {
+ switch (change.type()) {
+ case AutofillChange::ADD: {
+ os << "ADD";
+ break;
+ }
+ case AutofillChange::UPDATE: {
+ os << "UPDATE";
+ break;
+ }
+ case AutofillChange::REMOVE: {
+ os << "REMOVE";
+ break;
+ }
+ }
+ return os << " " << change.key();
+}
+
class WebDatabaseTest : public testing::Test {
protected:
@@ -87,7 +113,7 @@ class WebDatabaseTest : public testing::Test {
TEST_F(WebDatabaseTest, Keywords) {
WebDatabase db;
- EXPECT_TRUE(db.Init(file_));
+ ASSERT_TRUE(db.Init(file_));
TemplateURL template_url;
template_url.set_short_name(L"short_name");
@@ -148,7 +174,7 @@ TEST_F(WebDatabaseTest, Keywords) {
TEST_F(WebDatabaseTest, KeywordMisc) {
WebDatabase db;
- EXPECT_TRUE(db.Init(file_));
+ ASSERT_TRUE(db.Init(file_));
ASSERT_EQ(0, db.GetDefaulSearchProviderID());
ASSERT_EQ(0, db.GetBuitinKeywordVersion());
@@ -163,7 +189,7 @@ TEST_F(WebDatabaseTest, KeywordMisc) {
TEST_F(WebDatabaseTest, UpdateKeyword) {
WebDatabase db;
- EXPECT_TRUE(db.Init(file_));
+ ASSERT_TRUE(db.Init(file_));
TemplateURL template_url;
template_url.set_short_name(L"short_name");
@@ -225,7 +251,7 @@ TEST_F(WebDatabaseTest, UpdateKeyword) {
TEST_F(WebDatabaseTest, KeywordWithNoFavicon) {
WebDatabase db;
- EXPECT_TRUE(db.Init(file_));
+ ASSERT_TRUE(db.Init(file_));
TemplateURL template_url;
template_url.set_short_name(L"short_name");
@@ -252,7 +278,7 @@ TEST_F(WebDatabaseTest, KeywordWithNoFavicon) {
TEST_F(WebDatabaseTest, Logins) {
WebDatabase db;
- EXPECT_TRUE(db.Init(file_));
+ ASSERT_TRUE(db.Init(file_));
std::vector<PasswordForm*> result;
@@ -385,7 +411,7 @@ TEST_F(WebDatabaseTest, Logins) {
TEST_F(WebDatabaseTest, Autofill) {
WebDatabase db;
- EXPECT_TRUE(db.Init(file_));
+ ASSERT_TRUE(db.Init(file_));
Time t1 = Time::Now();
@@ -485,7 +511,27 @@ TEST_F(WebDatabaseTest, Autofill) {
// Removing all elements since the beginning of this function should remove
// everything from the database.
- EXPECT_TRUE(db.RemoveFormElementsAddedBetween(t1, Time()));
+ std::vector<AutofillChange> changes;
+ EXPECT_TRUE(db.RemoveFormElementsAddedBetween(t1, Time(), &changes));
+
+ const AutofillChange expected_changes[] = {
+ AutofillChange(AutofillChange::REMOVE,
+ AutofillKey(ASCIIToUTF16("Name"),
+ ASCIIToUTF16("Superman"))),
+ AutofillChange(AutofillChange::REMOVE,
+ AutofillKey(ASCIIToUTF16("Name"),
+ ASCIIToUTF16("Clark Kent"))),
+ AutofillChange(AutofillChange::REMOVE,
+ AutofillKey(ASCIIToUTF16("Name"),
+ ASCIIToUTF16("Clark Sutter"))),
+ AutofillChange(AutofillChange::REMOVE,
+ AutofillKey(ASCIIToUTF16("Favorite Color"),
+ ASCIIToUTF16("Green"))),
+ };
+ EXPECT_EQ(arraysize(expected_changes), changes.size());
+ for (size_t i = 0; i < arraysize(expected_changes); i++) {
+ EXPECT_EQ(expected_changes[i], changes[i]);
+ }
EXPECT_TRUE(db.GetIDAndCountOfFormElement(
FormField(string16(),
@@ -536,6 +582,44 @@ TEST_F(WebDatabaseTest, Autofill) {
EXPECT_EQ(kValue, v[0]);
}
+TEST_F(WebDatabaseTest, Autofill_RemoveBetweenChanges) {
+ WebDatabase db;
+ ASSERT_TRUE(db.Init(file_));
+
+ TimeDelta one_day(TimeDelta::FromDays(1));
+ Time t1 = Time::Now();
+ Time t2 = t1 + one_day;
+
+ EXPECT_TRUE(db.AddFormFieldValueTime(
+ FormField(string16(),
+ ASCIIToUTF16("Name"),
+ string16(),
+ ASCIIToUTF16("Superman")),
+ t1));
+ EXPECT_TRUE(db.AddFormFieldValueTime(
+ FormField(string16(),
+ ASCIIToUTF16("Name"),
+ string16(),
+ ASCIIToUTF16("Superman")),
+ t2));
+
+ std::vector<AutofillChange> changes;
+ EXPECT_TRUE(db.RemoveFormElementsAddedBetween(t1, t2, &changes));
+ ASSERT_EQ(1U, changes.size());
+ EXPECT_EQ(AutofillChange(AutofillChange::UPDATE,
+ AutofillKey(ASCIIToUTF16("Name"),
+ ASCIIToUTF16("Superman"))),
+ changes[0]);
+ changes.clear();
+
+ EXPECT_TRUE(db.RemoveFormElementsAddedBetween(t2, t2 + one_day, &changes));
+ ASSERT_EQ(1U, changes.size());
+ EXPECT_EQ(AutofillChange(AutofillChange::REMOVE,
+ AutofillKey(ASCIIToUTF16("Name"),
+ ASCIIToUTF16("Superman"))),
+ changes[0]);
+}
+
static bool AddTimestampedLogin(WebDatabase* db, std::string url,
const std::string& unique_string,
const Time& time) {
@@ -561,7 +645,7 @@ static void ClearResults(std::vector<PasswordForm*>* results) {
TEST_F(WebDatabaseTest, ClearPrivateData_SavedPasswords) {
WebDatabase db;
- EXPECT_TRUE(db.Init(file_));
+ ASSERT_TRUE(db.Init(file_));
std::vector<PasswordForm*> result;
@@ -603,7 +687,7 @@ TEST_F(WebDatabaseTest, ClearPrivateData_SavedPasswords) {
TEST_F(WebDatabaseTest, BlacklistedLogins) {
WebDatabase db;
- EXPECT_TRUE(db.Init(file_));
+ ASSERT_TRUE(db.Init(file_));
std::vector<PasswordForm*> result;
// Verify the database is empty.
@@ -642,7 +726,7 @@ TEST_F(WebDatabaseTest, BlacklistedLogins) {
TEST_F(WebDatabaseTest, WebAppHasAllImages) {
WebDatabase db;
- EXPECT_TRUE(db.Init(file_));
+ ASSERT_TRUE(db.Init(file_));
GURL url("http://google.com/");
// Initial value for unknown web app should be false.