Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/autofill/core/browser/webdata/autofill_table.h" | 5 #include "components/autofill/core/browser/webdata/autofill_table.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
| 22 #include "base/time/time.h" | 22 #include "base/time/time.h" |
| 23 #include "components/autofill/core/browser/autofill_country.h" | 23 #include "components/autofill/core/browser/autofill_country.h" |
| 24 #include "components/autofill/core/browser/autofill_profile.h" | 24 #include "components/autofill/core/browser/autofill_profile.h" |
| 25 #include "components/autofill/core/browser/autofill_type.h" | 25 #include "components/autofill/core/browser/autofill_type.h" |
| 26 #include "components/autofill/core/browser/credit_card.h" | 26 #include "components/autofill/core/browser/credit_card.h" |
| 27 #include "components/autofill/core/browser/personal_data_manager.h" | 27 #include "components/autofill/core/browser/personal_data_manager.h" |
| 28 #include "components/autofill/core/browser/webdata/autofill_change.h" | 28 #include "components/autofill/core/browser/webdata/autofill_change.h" |
| 29 #include "components/autofill/core/browser/webdata/autofill_entry.h" | 29 #include "components/autofill/core/browser/webdata/autofill_entry.h" |
| 30 #include "components/autofill/core/common/autofill_switches.h" | 30 #include "components/autofill/core/common/autofill_switches.h" |
| 31 #include "components/autofill/core/common/autofill_util.h" | |
| 31 #include "components/autofill/core/common/form_field_data.h" | 32 #include "components/autofill/core/common/form_field_data.h" |
| 32 #include "components/os_crypt/os_crypt.h" | 33 #include "components/os_crypt/os_crypt.h" |
| 33 #include "components/webdata/common/web_database.h" | 34 #include "components/webdata/common/web_database.h" |
| 34 #include "sql/statement.h" | 35 #include "sql/statement.h" |
| 35 #include "sql/transaction.h" | 36 #include "sql/transaction.h" |
| 36 #include "ui/base/l10n/l10n_util.h" | 37 #include "ui/base/l10n/l10n_util.h" |
| 37 #include "url/gurl.h" | 38 #include "url/gurl.h" |
| 38 | 39 |
| 39 using base::ASCIIToUTF16; | 40 using base::ASCIIToUTF16; |
| 40 using base::Time; | 41 using base::Time; |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 449 std::vector<AutofillChange>* changes) { | 450 std::vector<AutofillChange>* changes) { |
| 450 return AddFormFieldValueTime(element, changes, Time::Now()); | 451 return AddFormFieldValueTime(element, changes, Time::Now()); |
| 451 } | 452 } |
| 452 | 453 |
| 453 bool AutofillTable::GetFormValuesForElementName( | 454 bool AutofillTable::GetFormValuesForElementName( |
| 454 const base::string16& name, | 455 const base::string16& name, |
| 455 const base::string16& prefix, | 456 const base::string16& prefix, |
| 456 std::vector<base::string16>* values, | 457 std::vector<base::string16>* values, |
| 457 int limit) { | 458 int limit) { |
| 458 DCHECK(values); | 459 DCHECK(values); |
| 459 sql::Statement s; | 460 sql::Statement s1; |
| 461 sql::Statement s2; | |
|
please use gerrit instead
2015/06/30 19:06:23
I am beginning to think that it would be more corr
Pritam Nikam
2015/07/01 17:26:00
In that case, if |succeeded = s1.Succeeded()| is f
please use gerrit instead
2015/07/03 02:05:43
Is there a case when s1.Succeeded() is false that
Pritam Nikam
2015/07/03 16:21:27
Done.
I didn't find so far.
But logically, if |s
| |
| 460 | 462 |
| 461 if (prefix.empty()) { | 463 if (prefix.empty()) { |
| 462 s.Assign(db_->GetUniqueStatement( | 464 s1.Assign(db_->GetUniqueStatement( |
| 463 "SELECT value FROM autofill " | 465 "SELECT value FROM autofill " |
| 464 "WHERE name = ? " | 466 "WHERE name = ? " |
| 465 "ORDER BY count DESC " | 467 "ORDER BY count DESC " |
| 466 "LIMIT ?")); | 468 "LIMIT ?")); |
| 467 s.BindString16(0, name); | 469 s1.BindString16(0, name); |
| 468 s.BindInt(1, limit); | 470 s1.BindInt(1, limit); |
| 471 | |
| 472 values->clear(); | |
| 473 while (s1.Step()) | |
| 474 values->push_back(s1.ColumnString16(0)); | |
| 469 } else { | 475 } else { |
| 470 base::string16 prefix_lower = base::i18n::ToLower(prefix); | 476 base::string16 prefix_lower = base::i18n::ToLower(prefix); |
| 471 base::string16 next_prefix = prefix_lower; | 477 base::string16 next_prefix = prefix_lower; |
| 472 next_prefix[next_prefix.length() - 1]++; | 478 next_prefix[next_prefix.length() - 1]++; |
| 473 | 479 |
| 474 s.Assign(db_->GetUniqueStatement( | 480 s1.Assign(db_->GetUniqueStatement( |
| 475 "SELECT value FROM autofill " | 481 "SELECT value FROM autofill " |
| 476 "WHERE name = ? AND " | 482 "WHERE name = ? AND " |
| 477 "value_lower >= ? AND " | 483 "value_lower >= ? AND " |
| 478 "value_lower < ? " | 484 "value_lower < ? " |
| 479 "ORDER BY count DESC " | 485 "ORDER BY count DESC " |
| 480 "LIMIT ?")); | 486 "LIMIT ?")); |
| 481 s.BindString16(0, name); | 487 s1.BindString16(0, name); |
| 482 s.BindString16(1, prefix_lower); | 488 s1.BindString16(1, prefix_lower); |
| 483 s.BindString16(2, next_prefix); | 489 s1.BindString16(2, next_prefix); |
| 484 s.BindInt(3, limit); | 490 s1.BindInt(3, limit); |
| 491 | |
| 492 values->clear(); | |
| 493 while (s1.Step()) | |
| 494 values->push_back(s1.ColumnString16(0)); | |
| 495 | |
| 496 if (IsFeatureSubstringMatchEnabled()) { | |
| 497 s2.Assign(db_->GetUniqueStatement( | |
| 498 "SELECT value FROM autofill " | |
| 499 "WHERE name = ? AND (" | |
| 500 " value LIKE ? OR " | |
| 501 " value LIKE ? OR " | |
| 502 " value LIKE ? OR " | |
| 503 " value LIKE ? OR " | |
| 504 " value LIKE ? OR " | |
| 505 " value LIKE ? ESCAPE '!') " | |
| 506 "ORDER BY count DESC " | |
| 507 "LIMIT ?")); | |
| 508 s2.BindString16(0, name); | |
| 509 s2.BindString16( | |
| 510 1, base::ASCIIToUTF16("% ") + prefix_lower + base::ASCIIToUTF16("%")); | |
|
please use gerrit instead
2015/06/30 19:06:23
If "prefix_lower" contains "_", "%%", or "; DROP T
Pritam Nikam
2015/07/01 17:26:00
Yeah, there seems many problems :(
please use gerrit instead
2015/07/03 02:05:43
The fix is not to move SQL injection mitigation in
Pritam Nikam
2015/07/03 16:21:27
This SQL query does not work on my chromium Linux
| |
| 511 s2.BindString16( | |
| 512 2, base::ASCIIToUTF16("%.") + prefix_lower + base::ASCIIToUTF16("%")); | |
| 513 s2.BindString16( | |
| 514 3, base::ASCIIToUTF16("%,") + prefix_lower + base::ASCIIToUTF16("%")); | |
| 515 s2.BindString16( | |
| 516 4, base::ASCIIToUTF16("%-") + prefix_lower + base::ASCIIToUTF16("%")); | |
| 517 s2.BindString16( | |
| 518 5, base::ASCIIToUTF16("%@") + prefix_lower + base::ASCIIToUTF16("%")); | |
| 519 s2.BindString16(6, base::ASCIIToUTF16("%!_") + prefix_lower + | |
| 520 base::ASCIIToUTF16("%")); | |
|
please use gerrit instead
2015/06/30 19:06:23
I am very happy that this works. Good job! Would y
Pritam Nikam
2015/07/01 17:26:00
These doesn't work :(
| |
| 521 s2.BindInt(7, limit); | |
| 522 | |
| 523 // Append substring matched suggestions. | |
| 524 while (s2.Step()) | |
| 525 values->push_back(s2.ColumnString16(0)); | |
| 526 } | |
| 485 } | 527 } |
| 486 | 528 |
| 487 values->clear(); | 529 return s1.Succeeded() || s2.Succeeded(); |
| 488 while (s.Step()) | |
| 489 values->push_back(s.ColumnString16(0)); | |
| 490 return s.Succeeded(); | |
| 491 } | 530 } |
| 492 | 531 |
| 493 bool AutofillTable::HasFormElements() { | 532 bool AutofillTable::HasFormElements() { |
| 494 sql::Statement s(db_->GetUniqueStatement("SELECT COUNT(*) FROM autofill")); | 533 sql::Statement s(db_->GetUniqueStatement("SELECT COUNT(*) FROM autofill")); |
| 495 if (!s.Step()) { | 534 if (!s.Step()) { |
| 496 NOTREACHED(); | 535 NOTREACHED(); |
| 497 return false; | 536 return false; |
| 498 } | 537 } |
| 499 return s.ColumnInt(0) > 0; | 538 return s.ColumnInt(0) > 0; |
| 500 } | 539 } |
| (...skipping 1691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2192 insert.BindString16(index++, profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER)); | 2231 insert.BindString16(index++, profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER)); |
| 2193 insert.BindString(index++, profile.language_code()); | 2232 insert.BindString(index++, profile.language_code()); |
| 2194 insert.Run(); | 2233 insert.Run(); |
| 2195 insert.Reset(true); | 2234 insert.Reset(true); |
| 2196 } | 2235 } |
| 2197 | 2236 |
| 2198 return transaction.Commit(); | 2237 return transaction.Commit(); |
| 2199 } | 2238 } |
| 2200 | 2239 |
| 2201 } // namespace autofill | 2240 } // namespace autofill |
| OLD | NEW |