| 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 // We store at most 2 time stamps. If we remove both of them we should |
| 428 if (!AddToCountOfFormElement(itr->a, -how_many, &was_removed)) | 429 // delete the corresponding data. If we delete only one it could still be |
| 429 return false; | 430 // the last timestamp for the data, so check how many timestamps do remain. |
| 431 bool should_remove = (CountTimestampsData(itr->a) == 0); |
| 432 if (should_remove) { |
| 433 if (!RemoveFormElementForID(itr->a)) |
| 434 return false; |
| 435 } else { |
| 436 if (!AddToCountOfFormElement(itr->a, -how_many)) |
| 437 return false; |
| 438 } |
| 430 AutofillChange::Type change_type = | 439 AutofillChange::Type change_type = |
| 431 was_removed ? AutofillChange::REMOVE : AutofillChange::UPDATE; | 440 should_remove ? AutofillChange::REMOVE : AutofillChange::UPDATE; |
| 432 changes->push_back(AutofillChange(change_type, | 441 changes->push_back(AutofillChange(change_type, |
| 433 AutofillKey(itr->b, itr->c))); | 442 AutofillKey(itr->b, itr->c))); |
| 434 } | 443 } |
| 435 | 444 |
| 436 return true; | 445 return true; |
| 437 } | 446 } |
| 438 | 447 |
| 448 bool AutofillTable::RemoveExpiredFormElements( |
| 449 std::vector<AutofillChange>* changes) { |
| 450 DCHECK(changes); |
| 451 |
| 452 base::Time delete_end = AutofillEntry::ExpirationTime(); |
| 453 // Query for the pair_id, name, and value of all form elements that |
| 454 // were last used before the |delete_end|. |
| 455 sql::Statement select_for_delete(db_->GetUniqueStatement( |
| 456 "SELECT DISTINCT pair_id, name, value " |
| 457 "FROM autofill WHERE pair_id NOT IN " |
| 458 "(SELECT DISTINCT pair_id " |
| 459 "FROM autofill_dates WHERE date_created >= ?)")); |
| 460 select_for_delete.BindInt64(0, delete_end.ToTimeT()); |
| 461 AutofillElementList entries_to_delete; |
| 462 while (select_for_delete.Step()) { |
| 463 entries_to_delete.push_back(MakeTuple(select_for_delete.ColumnInt64(0), |
| 464 select_for_delete.ColumnString16(1), |
| 465 select_for_delete.ColumnString16(2))); |
| 466 } |
| 467 |
| 468 if (!select_for_delete.Succeeded()) |
| 469 return false; |
| 470 |
| 471 sql::Statement delete_data_statement(db_->GetUniqueStatement( |
| 472 "DELETE FROM autofill WHERE pair_id NOT IN (" |
| 473 "SELECT pair_id FROM autofill_dates WHERE date_created >= ?)")); |
| 474 delete_data_statement.BindInt64(0, delete_end.ToTimeT()); |
| 475 if (!delete_data_statement.Run()) |
| 476 return false; |
| 477 |
| 478 sql::Statement delete_times_statement(db_->GetUniqueStatement( |
| 479 "DELETE FROM autofill_dates WHERE pair_id NOT IN (" |
| 480 "SELECT pair_id FROM autofill_dates WHERE date_created >= ?)")); |
| 481 delete_times_statement.BindInt64(0, delete_end.ToTimeT()); |
| 482 if (!delete_times_statement.Run()) |
| 483 return false; |
| 484 |
| 485 // Cull remaining entries' timestamps. |
| 486 std::vector<AutofillEntry> entries; |
| 487 if (!GetAllAutofillEntries(&entries)) |
| 488 return false; |
| 489 sql::Statement cull_date_entry(db_->GetUniqueStatement( |
| 490 "DELETE FROM autofill_dates " |
| 491 "WHERE pair_id == (SELECT pair_id FROM autofill " |
| 492 "WHERE name = ? and value = ?)" |
| 493 "AND date_created != ? AND date_created != ?")); |
| 494 for (size_t i = 0; i < entries.size(); ++i) { |
| 495 cull_date_entry.BindString16(0, entries[i].key().name()); |
| 496 cull_date_entry.BindString16(1, entries[i].key().value()); |
| 497 cull_date_entry.BindInt64(2, |
| 498 entries[i].timestamps().empty() ? 0 : |
| 499 entries[i].timestamps().front().ToTimeT()); |
| 500 cull_date_entry.BindInt64(3, |
| 501 entries[i].timestamps().empty() ? 0 : |
| 502 entries[i].timestamps().back().ToTimeT()); |
| 503 if (!cull_date_entry.Run()) |
| 504 return false; |
| 505 cull_date_entry.Reset(); |
| 506 } |
| 507 |
| 508 changes->clear(); |
| 509 changes->reserve(entries_to_delete.size()); |
| 510 |
| 511 for (AutofillElementList::iterator it = entries_to_delete.begin(); |
| 512 it != entries_to_delete.end(); ++it) { |
| 513 changes->push_back(AutofillChange( |
| 514 AutofillChange::REMOVE, AutofillKey(it->b, it->c))); |
| 515 } |
| 516 return true; |
| 517 } |
| 518 |
| 439 bool AutofillTable::RemoveFormElementForTimeRange(int64 pair_id, | 519 bool AutofillTable::RemoveFormElementForTimeRange(int64 pair_id, |
| 440 const Time& delete_begin, | 520 const Time& delete_begin, |
| 441 const Time& delete_end, | 521 const Time& delete_end, |
| 442 int* how_many) { | 522 int* how_many) { |
| 443 sql::Statement s(db_->GetUniqueStatement( | 523 sql::Statement s(db_->GetUniqueStatement( |
| 444 "DELETE FROM autofill_dates WHERE pair_id = ? AND " | 524 "DELETE FROM autofill_dates WHERE pair_id = ? AND " |
| 445 "date_created >= ? AND date_created < ?")); | 525 "date_created >= ? AND date_created < ?")); |
| 446 s.BindInt64(0, pair_id); | 526 s.BindInt64(0, pair_id); |
| 447 s.BindInt64(1, delete_begin.is_null() ? 0 : delete_begin.ToTimeT()); | 527 s.BindInt64(1, delete_begin.is_null() ? 0 : delete_begin.ToTimeT()); |
| 448 s.BindInt64(2, delete_end.is_null() ? std::numeric_limits<int64>::max() : | 528 s.BindInt64(2, delete_end.is_null() ? std::numeric_limits<int64>::max() : |
| 449 delete_end.ToTimeT()); | 529 delete_end.ToTimeT()); |
| 450 | 530 |
| 451 bool result = s.Run(); | 531 bool result = s.Run(); |
| 452 if (how_many) | 532 if (how_many) |
| 453 *how_many = db_->GetLastChangeCount(); | 533 *how_many = db_->GetLastChangeCount(); |
| 454 | 534 |
| 455 return result; | 535 return result; |
| 456 } | 536 } |
| 457 | 537 |
| 538 int AutofillTable::CountTimestampsData(int64 pair_id) { |
| 539 sql::Statement s(db_->GetUniqueStatement( |
| 540 "SELECT COUNT(*) FROM autofill_dates WHERE pair_id = ?")); |
| 541 s.BindInt64(0, pair_id); |
| 542 if (!s.Step()) { |
| 543 NOTREACHED(); |
| 544 return 0; |
| 545 } else { |
| 546 return s.ColumnInt(0); |
| 547 } |
| 548 } |
| 549 |
| 458 bool AutofillTable::AddToCountOfFormElement(int64 pair_id, | 550 bool AutofillTable::AddToCountOfFormElement(int64 pair_id, |
| 459 int delta, | 551 int delta) { |
| 460 bool* was_removed) { | |
| 461 DCHECK(was_removed); | |
| 462 int count = 0; | 552 int count = 0; |
| 463 *was_removed = false; | |
| 464 | 553 |
| 465 if (!GetCountOfFormElement(pair_id, &count)) | 554 if (!GetCountOfFormElement(pair_id, &count)) |
| 466 return false; | 555 return false; |
| 467 | 556 |
| 468 if (count + delta == 0) { | 557 if (count + delta == 0) { |
| 469 if (!RemoveFormElementForID(pair_id)) | 558 // Should remove the element earlier in the code. |
| 470 return false; | 559 NOTREACHED(); |
| 471 *was_removed = true; | 560 return false; |
| 472 } else { | 561 } else { |
| 473 if (!SetCountOfFormElement(pair_id, count + delta)) | 562 if (!SetCountOfFormElement(pair_id, count + delta)) |
| 474 return false; | 563 return false; |
| 475 } | 564 } |
| 476 return true; | 565 return true; |
| 477 } | 566 } |
| 478 | 567 |
| 479 bool AutofillTable::GetIDAndCountOfFormElement( | 568 bool AutofillTable::GetIDAndCountOfFormElement( |
| 480 const FormField& element, | 569 const FormField& element, |
| 481 int64* pair_id, | 570 int64* pair_id, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 const Time& date_created) { | 634 const Time& date_created) { |
| 546 sql::Statement s(db_->GetUniqueStatement( | 635 sql::Statement s(db_->GetUniqueStatement( |
| 547 "INSERT INTO autofill_dates " | 636 "INSERT INTO autofill_dates " |
| 548 "(pair_id, date_created) VALUES (?, ?)")); | 637 "(pair_id, date_created) VALUES (?, ?)")); |
| 549 s.BindInt64(0, pair_id); | 638 s.BindInt64(0, pair_id); |
| 550 s.BindInt64(1, date_created.ToTimeT()); | 639 s.BindInt64(1, date_created.ToTimeT()); |
| 551 | 640 |
| 552 return s.Run(); | 641 return s.Run(); |
| 553 } | 642 } |
| 554 | 643 |
| 644 bool AutofillTable::DeleteLastAccess(int64 pair_id) { |
| 645 // Inner SELECT selects the newest |date_created| for a given |pair_id|. |
| 646 // DELETE deletes only that entry. |
| 647 sql::Statement s(db_->GetUniqueStatement( |
| 648 "DELETE FROM autofill_dates WHERE pair_id = ? and date_created IN " |
| 649 "(SELECT date_created FROM autofill_dates WHERE pair_id = ? " |
| 650 "ORDER BY date_created DESC LIMIT 1)")); |
| 651 s.BindInt64(0, pair_id); |
| 652 s.BindInt64(1, pair_id); |
| 653 |
| 654 return s.Run(); |
| 655 } |
| 656 |
| 555 bool AutofillTable::AddFormFieldValuesTime( | 657 bool AutofillTable::AddFormFieldValuesTime( |
| 556 const std::vector<FormField>& elements, | 658 const std::vector<FormField>& elements, |
| 557 std::vector<AutofillChange>* changes, | 659 std::vector<AutofillChange>* changes, |
| 558 Time time) { | 660 Time time) { |
| 559 // Only add one new entry for each unique element name. Use |seen_names| to | 661 // 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. | 662 // track this. Add up to |kMaximumUniqueNames| unique entries per form. |
| 561 const size_t kMaximumUniqueNames = 256; | 663 const size_t kMaximumUniqueNames = 256; |
| 562 std::set<string16> seen_names; | 664 std::set<string16> seen_names; |
| 563 bool result = true; | 665 bool result = true; |
| 564 for (std::vector<FormField>::const_iterator | 666 for (std::vector<FormField>::const_iterator itr = elements.begin(); |
| 565 itr = elements.begin(); | 667 itr != elements.end(); ++itr) { |
| 566 itr != elements.end(); | |
| 567 itr++) { | |
| 568 if (seen_names.size() >= kMaximumUniqueNames) | 668 if (seen_names.size() >= kMaximumUniqueNames) |
| 569 break; | 669 break; |
| 570 if (seen_names.find(itr->name) != seen_names.end()) | 670 if (seen_names.find(itr->name) != seen_names.end()) |
| 571 continue; | 671 continue; |
| 572 result = result && AddFormFieldValueTime(*itr, changes, time); | 672 result = result && AddFormFieldValueTime(*itr, changes, time); |
| 573 seen_names.insert(itr->name); | 673 seen_names.insert(itr->name); |
| 574 } | 674 } |
| 575 return result; | 675 return result; |
| 576 } | 676 } |
| 577 | 677 |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 | 826 |
| 727 if (!GetIDAndCountOfFormElement(element, &pair_id, &count)) | 827 if (!GetIDAndCountOfFormElement(element, &pair_id, &count)) |
| 728 return false; | 828 return false; |
| 729 | 829 |
| 730 if (count == 0 && !InsertFormElement(element, &pair_id)) | 830 if (count == 0 && !InsertFormElement(element, &pair_id)) |
| 731 return false; | 831 return false; |
| 732 | 832 |
| 733 if (!SetCountOfFormElement(pair_id, count + 1)) | 833 if (!SetCountOfFormElement(pair_id, count + 1)) |
| 734 return false; | 834 return false; |
| 735 | 835 |
| 836 // If we already have more than 2 times delete last one, before adding new |
| 837 // one. |
| 838 if (count >= 2 && !DeleteLastAccess(pair_id)) |
| 839 return false; |
| 840 |
| 736 if (!InsertPairIDAndDate(pair_id, time)) | 841 if (!InsertPairIDAndDate(pair_id, time)) |
| 737 return false; | 842 return false; |
| 738 | 843 |
| 739 AutofillChange::Type change_type = | 844 AutofillChange::Type change_type = |
| 740 count == 0 ? AutofillChange::ADD : AutofillChange::UPDATE; | 845 count == 0 ? AutofillChange::ADD : AutofillChange::UPDATE; |
| 741 changes->push_back( | 846 changes->push_back( |
| 742 AutofillChange(change_type, | 847 AutofillChange(change_type, |
| 743 AutofillKey(element.name, element.value))); | 848 AutofillKey(element.name, element.value))); |
| 744 return true; | 849 return true; |
| 745 } | 850 } |
| (...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1873 "WHERE guid=?")); | 1978 "WHERE guid=?")); |
| 1874 s_date.BindInt64(0, date_item->second); | 1979 s_date.BindInt64(0, date_item->second); |
| 1875 s_date.BindString(1, iter->guid()); | 1980 s_date.BindString(1, iter->guid()); |
| 1876 | 1981 |
| 1877 if (!s_date.Run()) | 1982 if (!s_date.Run()) |
| 1878 return false; | 1983 return false; |
| 1879 } | 1984 } |
| 1880 | 1985 |
| 1881 return true; | 1986 return true; |
| 1882 } | 1987 } |
| OLD | NEW |