Index: components/autofill/core/browser/webdata/autofill_table.cc |
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc |
index c337f60223f165cecc20a75e0ae7808ddaf7f800..b3f352b0119b12f0047f5d030124f5cdc15f4bf7 100644 |
--- a/components/autofill/core/browser/webdata/autofill_table.cc |
+++ b/components/autofill/core/browser/webdata/autofill_table.cc |
@@ -18,6 +18,7 @@ |
#include "base/logging.h" |
#include "base/numerics/safe_conversions.h" |
#include "base/strings/string_number_conversions.h" |
+#include "base/strings/string_util.h" |
#include "base/strings/utf_string_conversions.h" |
#include "base/time/time.h" |
#include "components/autofill/core/browser/autofill_country.h" |
@@ -28,6 +29,7 @@ |
#include "components/autofill/core/browser/webdata/autofill_change.h" |
#include "components/autofill/core/browser/webdata/autofill_entry.h" |
#include "components/autofill/core/common/autofill_switches.h" |
+#include "components/autofill/core/common/autofill_util.h" |
#include "components/autofill/core/common/form_field_data.h" |
#include "components/os_crypt/os_crypt.h" |
#include "components/webdata/common/web_database.h" |
@@ -368,6 +370,20 @@ CreditCard::ServerStatus ServerStatusStringToEnum(const std::string& status) { |
return CreditCard::OK; |
} |
+// Returns string with sustituted (_), (%) and (!) in supplied |str| by (!_), |
+// (!%) and (!!) respectively. |
+// For e.g. "ex!a_mp%le" -> "ex!!a!_mp!%le". |
+base::string16 SubstringSubstituteText(const base::string16& str) { |
+ base::string16 result; |
+ base::ReplaceChars(str, base::ASCIIToUTF16("!"), base::ASCIIToUTF16("!!"), |
+ &result); |
+ base::ReplaceChars(result, base::ASCIIToUTF16("_"), base::ASCIIToUTF16("!_"), |
+ &result); |
+ base::ReplaceChars(result, base::ASCIIToUTF16("%"), base::ASCIIToUTF16("!%"), |
+ &result); |
+ return result; |
+} |
+ |
} // namespace |
// The maximum length allowed for form data. |
@@ -456,9 +472,10 @@ bool AutofillTable::GetFormValuesForElementName( |
std::vector<base::string16>* values, |
int limit) { |
DCHECK(values); |
- sql::Statement s; |
+ bool succeeded = false; |
if (prefix.empty()) { |
+ sql::Statement s; |
s.Assign(db_->GetUniqueStatement( |
"SELECT value FROM autofill " |
"WHERE name = ? " |
@@ -466,28 +483,74 @@ bool AutofillTable::GetFormValuesForElementName( |
"LIMIT ?")); |
s.BindString16(0, name); |
s.BindInt(1, limit); |
+ |
+ values->clear(); |
+ while (s.Step()) |
+ values->push_back(s.ColumnString16(0)); |
+ |
+ succeeded = s.Succeeded(); |
} else { |
base::string16 prefix_lower = base::i18n::ToLower(prefix); |
base::string16 next_prefix = prefix_lower; |
next_prefix[next_prefix.length() - 1]++; |
- s.Assign(db_->GetUniqueStatement( |
+ sql::Statement s1; |
+ s1.Assign(db_->GetUniqueStatement( |
"SELECT value FROM autofill " |
"WHERE name = ? AND " |
"value_lower >= ? AND " |
"value_lower < ? " |
"ORDER BY count DESC " |
"LIMIT ?")); |
- s.BindString16(0, name); |
- s.BindString16(1, prefix_lower); |
- s.BindString16(2, next_prefix); |
- s.BindInt(3, limit); |
+ s1.BindString16(0, name); |
+ s1.BindString16(1, prefix_lower); |
+ s1.BindString16(2, next_prefix); |
+ s1.BindInt(3, limit); |
+ |
+ values->clear(); |
+ while (s1.Step()) |
+ values->push_back(s1.ColumnString16(0)); |
+ |
+ succeeded = s1.Succeeded(); |
+ |
+ if (IsFeatureSubstringMatchEnabled()) { |
+ base::string16 substituted_text = SubstringSubstituteText(prefix_lower); |
+ sql::Statement s2; |
+ s2.Assign(db_->GetUniqueStatement( |
+ "SELECT value FROM autofill " |
+ "WHERE name = ? AND (" |
+ " value LIKE ? ESCAPE '!' OR " |
+ " value LIKE ? ESCAPE '!' OR " |
+ " value LIKE ? ESCAPE '!' OR " |
+ " value LIKE ? ESCAPE '!' OR " |
+ " value LIKE ? ESCAPE '!' OR " |
+ " value LIKE ? ESCAPE '!') " |
+ "ORDER BY count DESC " |
+ "LIMIT ?")); |
+ s2.BindString16(0, name); |
+ s2.BindString16(1, base::ASCIIToUTF16("% ") + substituted_text + |
+ base::ASCIIToUTF16("%")); |
+ s2.BindString16(2, base::ASCIIToUTF16("%.") + substituted_text + |
+ base::ASCIIToUTF16("%")); |
+ s2.BindString16(3, base::ASCIIToUTF16("%,") + substituted_text + |
+ base::ASCIIToUTF16("%")); |
+ s2.BindString16(4, base::ASCIIToUTF16("%-") + substituted_text + |
+ base::ASCIIToUTF16("%")); |
+ s2.BindString16(5, base::ASCIIToUTF16("%@") + substituted_text + |
+ base::ASCIIToUTF16("%")); |
+ s2.BindString16(6, base::ASCIIToUTF16("%!_") + substituted_text + |
+ base::ASCIIToUTF16("%")); |
+ s2.BindInt(7, limit); |
+ |
+ // Append substring matched suggestions. |
+ while (s2.Step()) |
+ values->push_back(s2.ColumnString16(0)); |
+ |
+ succeeded |= s2.Succeeded(); |
+ } |
} |
- values->clear(); |
- while (s.Step()) |
- values->push_back(s.ColumnString16(0)); |
- return s.Succeeded(); |
+ return succeeded; |
} |
bool AutofillTable::HasFormElements() { |