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) { |
| 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)) { | |
| 433 was_removed = true; | |
| 434 if (!RemoveFormElementForID(itr->a)) | |
| 435 return false; | |
| 436 } else { | |
| 437 if (!AddToCountOfFormElement(itr->a, -how_many, &was_removed)) | |
|
Ilya Sherman
2012/03/21 21:20:53
As we discussed offline, I don't think we want to
GeorgeY
2012/03/21 22:10:56
Done.
| |
| 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 |delete_end|. | |
| 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()) { | |
| 544 NOTREACHED(); | |
| 545 return 0; | |
| 546 } else { | |
| 547 return s.ColumnInt(0); | |
| 548 } | |
| 549 } | |
| 550 | |
| 458 bool AutofillTable::AddToCountOfFormElement(int64 pair_id, | 551 bool AutofillTable::AddToCountOfFormElement(int64 pair_id, |
| 459 int delta, | 552 int delta, |
| 460 bool* was_removed) { | 553 bool* was_removed) { |
| 461 DCHECK(was_removed); | 554 DCHECK(was_removed); |
| 462 int count = 0; | 555 int count = 0; |
| 463 *was_removed = false; | 556 *was_removed = false; |
| 464 | 557 |
| 465 if (!GetCountOfFormElement(pair_id, &count)) | 558 if (!GetCountOfFormElement(pair_id, &count)) |
| 466 return false; | 559 return false; |
| 467 | 560 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 545 const Time& date_created) { | 638 const Time& date_created) { |
| 546 sql::Statement s(db_->GetUniqueStatement( | 639 sql::Statement s(db_->GetUniqueStatement( |
| 547 "INSERT INTO autofill_dates " | 640 "INSERT INTO autofill_dates " |
| 548 "(pair_id, date_created) VALUES (?, ?)")); | 641 "(pair_id, date_created) VALUES (?, ?)")); |
| 549 s.BindInt64(0, pair_id); | 642 s.BindInt64(0, pair_id); |
| 550 s.BindInt64(1, date_created.ToTimeT()); | 643 s.BindInt64(1, date_created.ToTimeT()); |
| 551 | 644 |
| 552 return s.Run(); | 645 return s.Run(); |
| 553 } | 646 } |
| 554 | 647 |
| 648 bool AutofillTable::DeleteLastAccess(int64 pair_id) { | |
| 649 // Inner SELECT selects the newest |date_created| for a given |pair_id|. | |
| 650 // DELETE deletes only that entry. | |
| 651 sql::Statement s(db_->GetUniqueStatement( | |
| 652 "DELETE FROM autofill_dates WHERE pair_id = ? and date_created IN " | |
| 653 "(SELECT date_created FROM autofill_dates WHERE pair_id = ? " | |
| 654 "ORDER BY date_created DESC LIMIT 1)")); | |
| 655 s.BindInt64(0, pair_id); | |
| 656 s.BindInt64(1, pair_id); | |
| 657 | |
| 658 return s.Run(); | |
| 659 } | |
| 660 | |
| 555 bool AutofillTable::AddFormFieldValuesTime( | 661 bool AutofillTable::AddFormFieldValuesTime( |
| 556 const std::vector<FormField>& elements, | 662 const std::vector<FormField>& elements, |
| 557 std::vector<AutofillChange>* changes, | 663 std::vector<AutofillChange>* changes, |
| 558 Time time) { | 664 Time time) { |
| 559 // Only add one new entry for each unique element name. Use |seen_names| to | 665 // 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. | 666 // track this. Add up to |kMaximumUniqueNames| unique entries per form. |
| 561 const size_t kMaximumUniqueNames = 256; | 667 const size_t kMaximumUniqueNames = 256; |
| 562 std::set<string16> seen_names; | 668 std::set<string16> seen_names; |
| 563 bool result = true; | 669 bool result = true; |
| 564 for (std::vector<FormField>::const_iterator | 670 for (std::vector<FormField>::const_iterator itr = elements.begin(); |
| 565 itr = elements.begin(); | 671 itr != elements.end(); ++itr) { |
| 566 itr != elements.end(); | |
| 567 itr++) { | |
| 568 if (seen_names.size() >= kMaximumUniqueNames) | 672 if (seen_names.size() >= kMaximumUniqueNames) |
| 569 break; | 673 break; |
| 570 if (seen_names.find(itr->name) != seen_names.end()) | 674 if (seen_names.find(itr->name) != seen_names.end()) |
| 571 continue; | 675 continue; |
| 572 result = result && AddFormFieldValueTime(*itr, changes, time); | 676 result = result && AddFormFieldValueTime(*itr, changes, time); |
| 573 seen_names.insert(itr->name); | 677 seen_names.insert(itr->name); |
| 574 } | 678 } |
| 575 return result; | 679 return result; |
| 576 } | 680 } |
| 577 | 681 |
| (...skipping 148 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 |