Chromium Code Reviews| 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/webdata/autofill_table.h" | 5 #include "chrome/browser/webdata/autofill_table.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <map> | 9 #include <map> |
| 10 #include <set> | 10 #include <set> |
| 11 #include <string> | 11 #include <string> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/i18n/case_conversion.h" | 14 #include "base/i18n/case_conversion.h" |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/string_number_conversions.h" | 16 #include "base/string_number_conversions.h" |
| 17 #include "base/time.h" | 17 #include "base/time.h" |
| 18 #include "base/tuple.h" | 18 #include "base/tuple.h" |
| 19 #include "chrome/browser/autofill/autofill_country.h" | 19 #include "chrome/browser/autofill/autofill_country.h" |
| 20 #include "chrome/browser/autofill/autofill_profile.h" | 20 #include "chrome/browser/autofill/autofill_profile.h" |
| 21 #include "chrome/browser/autofill/autofill_type.h" | 21 #include "chrome/browser/autofill/autofill_type.h" |
| 22 #include "chrome/browser/autofill/credit_card.h" | 22 #include "chrome/browser/autofill/credit_card.h" |
| 23 #include "chrome/browser/autofill/personal_data_manager.h" | 23 #include "chrome/browser/autofill/personal_data_manager.h" |
| 24 #include "chrome/browser/password_manager/encryptor.h" | 24 #include "chrome/browser/password_manager/encryptor.h" |
| 25 #include "chrome/browser/webdata/autofill_change.h" | 25 #include "chrome/browser/webdata/autofill_change.h" |
| 26 #include "chrome/browser/webdata/autofill_entry.h" | |
| 26 #include "chrome/common/guid.h" | 27 #include "chrome/common/guid.h" |
| 27 #include "sql/statement.h" | 28 #include "sql/statement.h" |
| 28 #include "ui/base/l10n/l10n_util.h" | 29 #include "ui/base/l10n/l10n_util.h" |
| 29 #include "webkit/forms/form_field.h" | 30 #include "webkit/forms/form_field.h" |
| 30 | 31 |
| 31 using base::Time; | 32 using base::Time; |
| 32 using webkit::forms::FormField; | 33 using webkit::forms::FormField; |
| 33 | 34 |
| 34 namespace { | 35 namespace { |
| 35 | 36 |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 AutofillElementList elements; | 412 AutofillElementList elements; |
| 412 while (s.Step()) { | 413 while (s.Step()) { |
| 413 elements.push_back(MakeTuple(s.ColumnInt64(0), | 414 elements.push_back(MakeTuple(s.ColumnInt64(0), |
| 414 s.ColumnString16(1), | 415 s.ColumnString16(1), |
| 415 s.ColumnString16(2))); | 416 s.ColumnString16(2))); |
| 416 } | 417 } |
| 417 if (!s.Succeeded()) | 418 if (!s.Succeeded()) |
| 418 return false; | 419 return false; |
| 419 | 420 |
| 420 for (AutofillElementList::iterator itr = elements.begin(); | 421 for (AutofillElementList::iterator itr = elements.begin(); |
| 421 itr != elements.end(); itr++) { | 422 itr != elements.end(); itr++) { |
|
Ilya Sherman
2012/03/20 21:25:13
nit: As long as you're editing nearby code... this
GeorgeY
2012/03/21 20:56:40
Done.
| |
| 422 int how_many = 0; | 423 int how_many = 0; |
| 423 if (!RemoveFormElementForTimeRange(itr->a, delete_begin, delete_end, | 424 if (!RemoveFormElementForTimeRange(itr->a, delete_begin, delete_end, |
| 424 &how_many)) { | 425 &how_many)) { |
| 425 return false; | 426 return false; |
| 426 } | 427 } |
| 427 bool was_removed = false; | 428 bool was_removed = false; |
| 428 if (!AddToCountOfFormElement(itr->a, -how_many, &was_removed)) | 429 // We store at most 2 time stamps. If we remove both of them we should |
| 429 return false; | 430 // delete the corresponding data. if we delete only one it could still be |
| 431 // the last timestamp for the data. | |
| 432 if (how_many == 2 || (how_many == 1 && CountTimestampsData(itr->a) == 0)) { | |
|
Ilya Sherman
2012/03/20 21:25:13
How about just always checking CountTimestampsData
GeorgeY
2012/03/21 20:56:40
Different counts. The other count functions are re
Ilya Sherman
2012/03/21 21:20:53
Ah, ok, I understand what you mean about this bein
GeorgeY
2012/03/21 22:10:56
Done.
| |
| 433 was_removed = true; | |
| 434 if (!RemoveFormElementForID(itr->a)) | |
| 435 return false; | |
| 436 } else { | |
| 437 if (!AddToCountOfFormElement(itr->a, -how_many, &was_removed)) | |
| 438 return false; | |
| 439 } | |
| 430 AutofillChange::Type change_type = | 440 AutofillChange::Type change_type = |
| 431 was_removed ? AutofillChange::REMOVE : AutofillChange::UPDATE; | 441 was_removed ? AutofillChange::REMOVE : AutofillChange::UPDATE; |
| 432 changes->push_back(AutofillChange(change_type, | 442 changes->push_back(AutofillChange(change_type, |
| 433 AutofillKey(itr->b, itr->c))); | 443 AutofillKey(itr->b, itr->c))); |
| 434 } | 444 } |
| 435 | 445 |
| 436 return true; | 446 return true; |
| 437 } | 447 } |
| 438 | 448 |
| 449 bool AutofillTable::RemoveExpiredFormElements( | |
| 450 std::vector<AutofillChange>* changes) { | |
| 451 DCHECK(changes); | |
| 452 | |
| 453 base::Time delete_end = AutofillEntry::ExpirationTime(); | |
| 454 // Query for the pair_id, name, and value of all form elements that | |
| 455 // were last used before the given time. | |
|
Ilya Sherman
2012/03/20 21:25:13
nit: "the given time" -> "|delete_end|"
GeorgeY
2012/03/21 20:56:40
Done.
| |
| 456 sql::Statement select_for_delete(db_->GetUniqueStatement( | |
| 457 "SELECT DISTINCT pair_id, name, value " | |
| 458 "FROM autofill WHERE pair_id NOT IN " | |
| 459 "(SELECT DISTINCT pair_id " | |
| 460 "FROM autofill_dates WHERE date_created >= ?)")); | |
| 461 select_for_delete.BindInt64(0, delete_end.ToTimeT()); | |
| 462 AutofillElementList entries_to_delete; | |
| 463 while (select_for_delete.Step()) { | |
| 464 entries_to_delete.push_back(MakeTuple(select_for_delete.ColumnInt64(0), | |
| 465 select_for_delete.ColumnString16(1), | |
| 466 select_for_delete.ColumnString16(2))); | |
| 467 } | |
| 468 | |
| 469 if (!select_for_delete.Succeeded()) | |
| 470 return false; | |
| 471 | |
| 472 sql::Statement delete_data_statement(db_->GetUniqueStatement( | |
| 473 "DELETE FROM autofill WHERE pair_id NOT IN (" | |
| 474 "SELECT pair_id FROM autofill_dates WHERE date_created >= ?)")); | |
| 475 delete_data_statement.BindInt64(0, delete_end.ToTimeT()); | |
| 476 if (!delete_data_statement.Run()) | |
| 477 return false; | |
| 478 | |
| 479 sql::Statement delete_times_statement(db_->GetUniqueStatement( | |
| 480 "DELETE FROM autofill_dates WHERE pair_id NOT IN (" | |
| 481 "SELECT pair_id FROM autofill_dates WHERE date_created >= ?)")); | |
| 482 delete_times_statement.BindInt64(0, delete_end.ToTimeT()); | |
| 483 if (!delete_times_statement.Run()) | |
| 484 return false; | |
| 485 | |
| 486 // Cull remaining entries' timestamps. | |
| 487 std::vector<AutofillEntry> entries; | |
| 488 if (!GetAllAutofillEntries(&entries)) | |
| 489 return false; | |
| 490 sql::Statement cull_date_entry(db_->GetUniqueStatement( | |
| 491 "DELETE FROM autofill_dates " | |
| 492 "WHERE pair_id == (SELECT pair_id FROM autofill " | |
| 493 "WHERE name = ? and value = ?)" | |
| 494 "AND date_created != ? AND date_created != ?")); | |
| 495 for (size_t i = 0; i < entries.size(); ++i) { | |
| 496 cull_date_entry.BindString16(0, entries[i].key().name()); | |
| 497 cull_date_entry.BindString16(1, entries[i].key().value()); | |
| 498 cull_date_entry.BindInt64(2, | |
| 499 entries[i].timestamps().empty() ? 0 : | |
| 500 entries[i].timestamps().front().ToTimeT()); | |
| 501 cull_date_entry.BindInt64(3, | |
| 502 entries[i].timestamps().empty() ? 0 : | |
| 503 entries[i].timestamps().back().ToTimeT()); | |
| 504 if (!cull_date_entry.Run()) | |
| 505 return false; | |
| 506 cull_date_entry.Reset(); | |
| 507 } | |
| 508 | |
| 509 changes->clear(); | |
| 510 changes->reserve(entries_to_delete.size()); | |
| 511 | |
| 512 for (AutofillElementList::iterator it = entries_to_delete.begin(); | |
| 513 it != entries_to_delete.end(); ++it) { | |
| 514 changes->push_back(AutofillChange( | |
| 515 AutofillChange::REMOVE, AutofillKey(it->b, it->c))); | |
| 516 } | |
| 517 return true; | |
| 518 } | |
| 519 | |
| 439 bool AutofillTable::RemoveFormElementForTimeRange(int64 pair_id, | 520 bool AutofillTable::RemoveFormElementForTimeRange(int64 pair_id, |
| 440 const Time& delete_begin, | 521 const Time& delete_begin, |
| 441 const Time& delete_end, | 522 const Time& delete_end, |
| 442 int* how_many) { | 523 int* how_many) { |
| 443 sql::Statement s(db_->GetUniqueStatement( | 524 sql::Statement s(db_->GetUniqueStatement( |
| 444 "DELETE FROM autofill_dates WHERE pair_id = ? AND " | 525 "DELETE FROM autofill_dates WHERE pair_id = ? AND " |
| 445 "date_created >= ? AND date_created < ?")); | 526 "date_created >= ? AND date_created < ?")); |
| 446 s.BindInt64(0, pair_id); | 527 s.BindInt64(0, pair_id); |
| 447 s.BindInt64(1, delete_begin.is_null() ? 0 : delete_begin.ToTimeT()); | 528 s.BindInt64(1, delete_begin.is_null() ? 0 : delete_begin.ToTimeT()); |
| 448 s.BindInt64(2, delete_end.is_null() ? std::numeric_limits<int64>::max() : | 529 s.BindInt64(2, delete_end.is_null() ? std::numeric_limits<int64>::max() : |
| 449 delete_end.ToTimeT()); | 530 delete_end.ToTimeT()); |
| 450 | 531 |
| 451 bool result = s.Run(); | 532 bool result = s.Run(); |
| 452 if (how_many) | 533 if (how_many) |
| 453 *how_many = db_->GetLastChangeCount(); | 534 *how_many = db_->GetLastChangeCount(); |
| 454 | 535 |
| 455 return result; | 536 return result; |
| 456 } | 537 } |
| 457 | 538 |
| 539 int AutofillTable::CountTimestampsData(int64 pair_id) { | |
| 540 sql::Statement s(db_->GetUniqueStatement( | |
| 541 "SELECT COUNT(*) FROM autofill_dates WHERE pair_id = ?")); | |
| 542 s.BindInt64(0, pair_id); | |
| 543 if (!s.Step()) | |
|
Ilya Sherman
2012/03/20 21:25:13
nit: Should this if-stmt include a NOTREACHED()?
GeorgeY
2012/03/21 20:56:40
Done.
| |
| 544 return 0; | |
| 545 else | |
| 546 return s.ColumnInt(0); | |
| 547 } | |
| 548 | |
| 458 bool AutofillTable::AddToCountOfFormElement(int64 pair_id, | 549 bool AutofillTable::AddToCountOfFormElement(int64 pair_id, |
| 459 int delta, | 550 int delta, |
| 460 bool* was_removed) { | 551 bool* was_removed) { |
| 461 DCHECK(was_removed); | 552 DCHECK(was_removed); |
| 462 int count = 0; | 553 int count = 0; |
| 463 *was_removed = false; | 554 *was_removed = false; |
| 464 | 555 |
| 465 if (!GetCountOfFormElement(pair_id, &count)) | 556 if (!GetCountOfFormElement(pair_id, &count)) |
| 466 return false; | 557 return false; |
| 467 | 558 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 545 const Time& date_created) { | 636 const Time& date_created) { |
| 546 sql::Statement s(db_->GetUniqueStatement( | 637 sql::Statement s(db_->GetUniqueStatement( |
| 547 "INSERT INTO autofill_dates " | 638 "INSERT INTO autofill_dates " |
| 548 "(pair_id, date_created) VALUES (?, ?)")); | 639 "(pair_id, date_created) VALUES (?, ?)")); |
| 549 s.BindInt64(0, pair_id); | 640 s.BindInt64(0, pair_id); |
| 550 s.BindInt64(1, date_created.ToTimeT()); | 641 s.BindInt64(1, date_created.ToTimeT()); |
| 551 | 642 |
| 552 return s.Run(); | 643 return s.Run(); |
| 553 } | 644 } |
| 554 | 645 |
| 646 bool AutofillTable::DeleteLastAccess(int64 pair_id) { | |
| 647 // Inner SELECT selects the newest |date_created| for a given |pair_id|. | |
| 648 // DELETE deletes only that entry. | |
| 649 sql::Statement s(db_->GetUniqueStatement( | |
| 650 "DELETE FROM autofill_dates WHERE pair_id = ? and date_created IN " | |
| 651 "(SELECT date_created FROM autofill_dates WHERE pair_id = ? " | |
| 652 "ORDER BY date_created DESC LIMIT 1)")); | |
| 653 s.BindInt64(0, pair_id); | |
| 654 s.BindInt64(1, pair_id); | |
| 655 | |
| 656 return s.Run(); | |
| 657 } | |
| 658 | |
| 555 bool AutofillTable::AddFormFieldValuesTime( | 659 bool AutofillTable::AddFormFieldValuesTime( |
| 556 const std::vector<FormField>& elements, | 660 const std::vector<FormField>& elements, |
| 557 std::vector<AutofillChange>* changes, | 661 std::vector<AutofillChange>* changes, |
| 558 Time time) { | 662 Time time) { |
| 559 // Only add one new entry for each unique element name. Use |seen_names| to | 663 // Only add one new entry for each unique element name. Use |seen_names| to |
| 560 // track this. Add up to |kMaximumUniqueNames| unique entries per form. | 664 // track this. Add up to |kMaximumUniqueNames| unique entries per form. |
| 561 const size_t kMaximumUniqueNames = 256; | 665 const size_t kMaximumUniqueNames = 256; |
| 562 std::set<string16> seen_names; | 666 std::set<string16> seen_names; |
| 563 bool result = true; | 667 bool result = true; |
| 564 for (std::vector<FormField>::const_iterator | 668 for (std::vector<FormField>::const_iterator |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 726 | 830 |
| 727 if (!GetIDAndCountOfFormElement(element, &pair_id, &count)) | 831 if (!GetIDAndCountOfFormElement(element, &pair_id, &count)) |
| 728 return false; | 832 return false; |
| 729 | 833 |
| 730 if (count == 0 && !InsertFormElement(element, &pair_id)) | 834 if (count == 0 && !InsertFormElement(element, &pair_id)) |
| 731 return false; | 835 return false; |
| 732 | 836 |
| 733 if (!SetCountOfFormElement(pair_id, count + 1)) | 837 if (!SetCountOfFormElement(pair_id, count + 1)) |
| 734 return false; | 838 return false; |
| 735 | 839 |
| 840 // If we already have more than 2 times delete last one, before adding new | |
| 841 // one. | |
| 842 if (count >= 2 && !DeleteLastAccess(pair_id)) | |
| 843 return false; | |
| 844 | |
| 736 if (!InsertPairIDAndDate(pair_id, time)) | 845 if (!InsertPairIDAndDate(pair_id, time)) |
| 737 return false; | 846 return false; |
| 738 | 847 |
| 739 AutofillChange::Type change_type = | 848 AutofillChange::Type change_type = |
| 740 count == 0 ? AutofillChange::ADD : AutofillChange::UPDATE; | 849 count == 0 ? AutofillChange::ADD : AutofillChange::UPDATE; |
| 741 changes->push_back( | 850 changes->push_back( |
| 742 AutofillChange(change_type, | 851 AutofillChange(change_type, |
| 743 AutofillKey(element.name, element.value))); | 852 AutofillKey(element.name, element.value))); |
| 744 return true; | 853 return true; |
| 745 } | 854 } |
| (...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1873 "WHERE guid=?")); | 1982 "WHERE guid=?")); |
| 1874 s_date.BindInt64(0, date_item->second); | 1983 s_date.BindInt64(0, date_item->second); |
| 1875 s_date.BindString(1, iter->guid()); | 1984 s_date.BindString(1, iter->guid()); |
| 1876 | 1985 |
| 1877 if (!s_date.Run()) | 1986 if (!s_date.Run()) |
| 1878 return false; | 1987 return false; |
| 1879 } | 1988 } |
| 1880 | 1989 |
| 1881 return true; | 1990 return true; |
| 1882 } | 1991 } |
| OLD | NEW |