Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(245)

Side by Side Diff: components/autofill/core/browser/form_structure.cc

Issue 2318533002: [Password Generation] Use signatures for form matching (Closed)
Patch Set: Rebase Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/form_structure.h" 5 #include "components/autofill/core/browser/form_structure.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <map> 10 #include <map>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/command_line.h" 13 #include "base/command_line.h"
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/metrics/field_trial.h" 16 #include "base/metrics/field_trial.h"
17 #include "base/sha1.h" 17 #include "base/sha1.h"
18 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/string_split.h" 19 #include "base/strings/string_split.h"
20 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
21 #include "base/strings/stringprintf.h" 21 #include "base/strings/stringprintf.h"
22 #include "base/strings/utf_string_conversions.h" 22 #include "base/strings/utf_string_conversions.h"
23 #include "base/time/time.h" 23 #include "base/time/time.h"
24 #include "components/autofill/core/browser/autofill_metrics.h" 24 #include "components/autofill/core/browser/autofill_metrics.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/field_candidates.h" 26 #include "components/autofill/core/browser/field_candidates.h"
27 #include "components/autofill/core/browser/field_types.h" 27 #include "components/autofill/core/browser/field_types.h"
28 #include "components/autofill/core/browser/form_field.h" 28 #include "components/autofill/core/browser/form_field.h"
29 #include "components/autofill/core/common/autofill_constants.h" 29 #include "components/autofill/core/common/autofill_constants.h"
30 #include "components/autofill/core/common/autofill_util.h"
30 #include "components/autofill/core/common/form_data.h" 31 #include "components/autofill/core/common/form_data.h"
31 #include "components/autofill/core/common/form_data_predictions.h" 32 #include "components/autofill/core/common/form_data_predictions.h"
32 #include "components/autofill/core/common/form_field_data.h" 33 #include "components/autofill/core/common/form_field_data.h"
33 #include "components/autofill/core/common/form_field_data_predictions.h" 34 #include "components/autofill/core/common/form_field_data_predictions.h"
35 #include "components/autofill/core/common/signatures_util.h"
34 #include "components/rappor/rappor_service.h" 36 #include "components/rappor/rappor_service.h"
35 #include "components/rappor/rappor_utils.h" 37 #include "components/rappor/rappor_utils.h"
36 #include "third_party/re2/src/re2/re2.h"
37 38
38 namespace autofill { 39 namespace autofill {
39 namespace { 40 namespace {
40 41
41 const char kClientVersion[] = "6.1.1715.1442/en (GGLL)"; 42 const char kClientVersion[] = "6.1.1715.1442/en (GGLL)";
42 const char kBillingMode[] = "billing"; 43 const char kBillingMode[] = "billing";
43 const char kShippingMode[] = "shipping"; 44 const char kShippingMode[] = "shipping";
44 45
45 // Strip away >= 5 consecutive digits.
46 const char kIgnorePatternInFieldName[] = "\\d{5,}";
47
48 // A form is considered to have a high prediction mismatch rate if the number of 46 // A form is considered to have a high prediction mismatch rate if the number of
49 // mismatches exceeds this threshold. 47 // mismatches exceeds this threshold.
50 const int kNumberOfMismatchesThreshold = 3; 48 const int kNumberOfMismatchesThreshold = 3;
51 49
52 // Only removing common name prefixes if we have a minimum number of fields and 50 // Only removing common name prefixes if we have a minimum number of fields and
53 // a minimum prefix length. These values are chosen to avoid cases such as two 51 // a minimum prefix length. These values are chosen to avoid cases such as two
54 // fields with "address1" and "address2" and be effective against web frameworks 52 // fields with "address1" and "address2" and be effective against web frameworks
55 // which prepend prefixes such as "ctl01$ctl00$MainContentRegion$" on all 53 // which prepend prefixes such as "ctl01$ctl00$MainContentRegion$" on all
56 // fields. 54 // fields.
57 const int kCommonNamePrefixRemovalFieldThreshold = 3; 55 const int kCommonNamePrefixRemovalFieldThreshold = 3;
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 263
266 if (autocomplete_attribute_value == "tel-extension") 264 if (autocomplete_attribute_value == "tel-extension")
267 return HTML_TYPE_TEL_EXTENSION; 265 return HTML_TYPE_TEL_EXTENSION;
268 266
269 if (autocomplete_attribute_value == "email") 267 if (autocomplete_attribute_value == "email")
270 return HTML_TYPE_EMAIL; 268 return HTML_TYPE_EMAIL;
271 269
272 return HTML_TYPE_UNRECOGNIZED; 270 return HTML_TYPE_UNRECOGNIZED;
273 } 271 }
274 272
275 std::string StripDigitsIfRequired(const base::string16& input) {
276 std::string return_string = base::UTF16ToUTF8(input);
277
278 re2::RE2::GlobalReplace(&return_string, re2::RE2(kIgnorePatternInFieldName),
279 std::string());
280 return return_string;
281 }
282
283 std::ostream& operator<<( 273 std::ostream& operator<<(
284 std::ostream& out, 274 std::ostream& out,
285 const autofill::AutofillQueryResponseContents& response) { 275 const autofill::AutofillQueryResponseContents& response) {
286 out << "upload_required: " << response.upload_required(); 276 out << "upload_required: " << response.upload_required();
287 for (const auto& field : response.field()) { 277 for (const auto& field : response.field()) {
288 out << "\nautofill_type: " << field.autofill_type(); 278 out << "\nautofill_type: " << field.autofill_type();
289 } 279 }
290 return out; 280 return out;
291 } 281 }
292 282
(...skipping 17 matching lines...) Expand all
310 has_author_specified_types_(false), 300 has_author_specified_types_(false),
311 has_author_specified_sections_(false), 301 has_author_specified_sections_(false),
312 was_parsed_for_autocomplete_attributes_(false), 302 was_parsed_for_autocomplete_attributes_(false),
313 has_password_field_(false), 303 has_password_field_(false),
314 is_form_tag_(form.is_form_tag), 304 is_form_tag_(form.is_form_tag),
315 is_formless_checkout_(form.is_formless_checkout), 305 is_formless_checkout_(form.is_formless_checkout),
316 all_fields_are_passwords_(true) { 306 all_fields_are_passwords_(true) {
317 // Copy the form fields. 307 // Copy the form fields.
318 std::map<base::string16, size_t> unique_names; 308 std::map<base::string16, size_t> unique_names;
319 for (const FormFieldData& field : form.fields) { 309 for (const FormFieldData& field : form.fields) {
320 if (!ShouldSkipField(field)) { 310 if (!ShouldSkipField(field))
321 // Add all supported form fields (including with empty names) to the
322 // signature. This is a requirement for Autofill servers.
323 form_signature_field_names_.append("&");
324 form_signature_field_names_.append(StripDigitsIfRequired(field.name));
325
326 ++active_field_count_; 311 ++active_field_count_;
327 }
328 312
329 if (field.form_control_type == "password") 313 if (field.form_control_type == "password")
330 has_password_field_ = true; 314 has_password_field_ = true;
331 else 315 else
332 all_fields_are_passwords_ = false; 316 all_fields_are_passwords_ = false;
333 317
334 // Generate a unique name for this field by appending a counter to the name. 318 // Generate a unique name for this field by appending a counter to the name.
335 // Make sure to prepend the counter with a non-numeric digit so that we are 319 // Make sure to prepend the counter with a non-numeric digit so that we are
336 // guaranteed to avoid collisions. 320 // guaranteed to avoid collisions.
337 base::string16 unique_name = 321 base::string16 unique_name =
338 field.name + base::ASCIIToUTF16("_") + 322 field.name + base::ASCIIToUTF16("_") +
339 base::SizeTToString16(++unique_names[field.name]); 323 base::SizeTToString16(++unique_names[field.name]);
340 fields_.push_back(new AutofillField(field, unique_name)); 324 fields_.push_back(new AutofillField(field, unique_name));
341 } 325 }
342 326
327 form_signature_ = autofill::CalculateFormSignature(form);
343 // Do further processing on the fields, as needed. 328 // Do further processing on the fields, as needed.
344 ProcessExtractedFields(); 329 ProcessExtractedFields();
345 } 330 }
346 331
347 FormStructure::~FormStructure() {} 332 FormStructure::~FormStructure() {}
348 333
349 void FormStructure::DetermineHeuristicTypes() { 334 void FormStructure::DetermineHeuristicTypes() {
350 const auto determine_heuristic_types_start_time = base::TimeTicks::Now(); 335 const auto determine_heuristic_types_start_time = base::TimeTicks::Now();
351 336
352 // First, try to detect field types based on each field's |autocomplete| 337 // First, try to detect field types based on each field's |autocomplete|
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 // are uploading. 381 // are uploading.
397 for (const AutofillField* field : *this) { 382 for (const AutofillField* field : *this) {
398 for (const auto& type : field->possible_types()) { 383 for (const auto& type : field->possible_types()) {
399 DCHECK(type == UNKNOWN_TYPE || type == EMPTY_TYPE || 384 DCHECK(type == UNKNOWN_TYPE || type == EMPTY_TYPE ||
400 available_field_types.count(type)); 385 available_field_types.count(type));
401 } 386 }
402 } 387 }
403 388
404 upload->set_submission(observed_submission); 389 upload->set_submission(observed_submission);
405 upload->set_client_version(kClientVersion); 390 upload->set_client_version(kClientVersion);
406 upload->set_form_signature(FormSignature64Bit()); 391 upload->set_form_signature(form_signature());
407 upload->set_autofill_used(form_was_autofilled); 392 upload->set_autofill_used(form_was_autofilled);
408 upload->set_data_present(EncodeFieldTypes(available_field_types)); 393 upload->set_data_present(EncodeFieldTypes(available_field_types));
409 394
410 if (IsAutofillFieldMetadataEnabled()) { 395 if (IsAutofillFieldMetadataEnabled()) {
411 upload->set_action_signature(Hash64Bit(target_url_.host())); 396 upload->set_action_signature(StrToHash64Bit(target_url_.host()));
412 if (!form_name().empty()) 397 if (!form_name().empty())
413 upload->set_form_name(base::UTF16ToUTF8(form_name())); 398 upload->set_form_name(base::UTF16ToUTF8(form_name()));
414 } 399 }
415 400
416 if (!login_form_signature.empty()) { 401 if (!login_form_signature.empty()) {
417 uint64_t login_sig; 402 uint64_t login_sig;
418 if (base::StringToUint64(login_form_signature, &login_sig)) 403 if (base::StringToUint64(login_form_signature, &login_sig))
419 upload->set_login_form_signature(login_sig); 404 upload->set_login_form_signature(login_sig);
420 } 405 }
421 406
(...skipping 12 matching lines...) Expand all
434 DCHECK(encoded_signatures); 419 DCHECK(encoded_signatures);
435 encoded_signatures->clear(); 420 encoded_signatures->clear();
436 encoded_signatures->reserve(forms.size()); 421 encoded_signatures->reserve(forms.size());
437 422
438 query->set_client_version(kClientVersion); 423 query->set_client_version(kClientVersion);
439 424
440 // Some badly formatted web sites repeat forms - detect that and encode only 425 // Some badly formatted web sites repeat forms - detect that and encode only
441 // one form as returned data would be the same for all the repeated forms. 426 // one form as returned data would be the same for all the repeated forms.
442 std::set<std::string> processed_forms; 427 std::set<std::string> processed_forms;
443 for (const auto* form : forms) { 428 for (const auto* form : forms) {
444 std::string signature(form->FormSignature()); 429 std::string signature(form->FormSignatureAsStr());
445 if (processed_forms.find(signature) != processed_forms.end()) 430 if (processed_forms.find(signature) != processed_forms.end())
446 continue; 431 continue;
447 processed_forms.insert(signature); 432 processed_forms.insert(signature);
448 if (form->IsMalformed()) 433 if (form->IsMalformed())
449 continue; 434 continue;
450 435
451 form->EncodeFormForQuery(query->add_form()); 436 form->EncodeFormForQuery(query->add_form());
452 437
453 encoded_signatures->push_back(signature); 438 encoded_signatures->push_back(signature);
454 } 439 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 std::vector<FormDataPredictions> FormStructure::GetFieldTypePredictions( 523 std::vector<FormDataPredictions> FormStructure::GetFieldTypePredictions(
539 const std::vector<FormStructure*>& form_structures) { 524 const std::vector<FormStructure*>& form_structures) {
540 std::vector<FormDataPredictions> forms; 525 std::vector<FormDataPredictions> forms;
541 forms.reserve(form_structures.size()); 526 forms.reserve(form_structures.size());
542 for (const FormStructure* form_structure : form_structures) { 527 for (const FormStructure* form_structure : form_structures) {
543 FormDataPredictions form; 528 FormDataPredictions form;
544 form.data.name = form_structure->form_name_; 529 form.data.name = form_structure->form_name_;
545 form.data.origin = form_structure->source_url_; 530 form.data.origin = form_structure->source_url_;
546 form.data.action = form_structure->target_url_; 531 form.data.action = form_structure->target_url_;
547 form.data.is_form_tag = form_structure->is_form_tag_; 532 form.data.is_form_tag = form_structure->is_form_tag_;
548 form.signature = form_structure->FormSignature(); 533 form.signature = form_structure->FormSignatureAsStr();
549 534
550 for (const AutofillField* field : form_structure->fields_) { 535 for (const AutofillField* field : form_structure->fields_) {
551 form.data.fields.push_back(FormFieldData(*field)); 536 form.data.fields.push_back(FormFieldData(*field));
552 537
553 FormFieldDataPredictions annotated_field; 538 FormFieldDataPredictions annotated_field;
554 annotated_field.signature = field->FieldSignature(); 539 annotated_field.signature = field->FieldSignatureAsStr();
555 annotated_field.heuristic_type = 540 annotated_field.heuristic_type =
556 AutofillType(field->heuristic_type()).ToString(); 541 AutofillType(field->heuristic_type()).ToString();
557 annotated_field.server_type = 542 annotated_field.server_type =
558 AutofillType(field->server_type()).ToString(); 543 AutofillType(field->server_type()).ToString();
559 annotated_field.overall_type = field->Type().ToString(); 544 annotated_field.overall_type = field->Type().ToString();
560 annotated_field.parseable_name = 545 annotated_field.parseable_name =
561 base::UTF16ToUTF8(field->parseable_name()); 546 base::UTF16ToUTF8(field->parseable_name());
562 form.fields.push_back(annotated_field); 547 form.fields.push_back(annotated_field);
563 } 548 }
564 549
565 forms.push_back(form); 550 forms.push_back(form);
566 } 551 }
567 return forms; 552 return forms;
568 } 553 }
569 554
570 // static 555 // static
571 bool FormStructure::IsAutofillFieldMetadataEnabled() { 556 bool FormStructure::IsAutofillFieldMetadataEnabled() {
572 const std::string group_name = 557 const std::string group_name =
573 base::FieldTrialList::FindFullName("AutofillFieldMetadata"); 558 base::FieldTrialList::FindFullName("AutofillFieldMetadata");
574 return base::StartsWith(group_name, "Enabled", base::CompareCase::SENSITIVE); 559 return base::StartsWith(group_name, "Enabled", base::CompareCase::SENSITIVE);
575 } 560 }
576 561
577 std::string FormStructure::FormSignature() const { 562 std::string FormStructure::FormSignatureAsStr() const {
578 return base::Uint64ToString(FormSignature64Bit()); 563 return base::Uint64ToString(form_signature());
579 } 564 }
580 565
581 bool FormStructure::IsAutofillable() const { 566 bool FormStructure::IsAutofillable() const {
582 if (autofill_count() < kRequiredFieldsForPredictionRoutines) 567 if (autofill_count() < kRequiredFieldsForPredictionRoutines)
583 return false; 568 return false;
584 569
585 return ShouldBeParsed(); 570 return ShouldBeParsed();
586 } 571 }
587 572
588 bool FormStructure::IsCompleteCreditCardForm() const { 573 bool FormStructure::IsCompleteCreditCardForm() const {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 return (has_password_field_ || 620 return (has_password_field_ ||
636 active_field_count() >= kRequiredFieldsForPredictionRoutines) && 621 active_field_count() >= kRequiredFieldsForPredictionRoutines) &&
637 ShouldBeParsed(); 622 ShouldBeParsed();
638 } 623 }
639 624
640 void FormStructure::UpdateFromCache(const FormStructure& cached_form) { 625 void FormStructure::UpdateFromCache(const FormStructure& cached_form) {
641 // Map from field signatures to cached fields. 626 // Map from field signatures to cached fields.
642 std::map<std::string, const AutofillField*> cached_fields; 627 std::map<std::string, const AutofillField*> cached_fields;
643 for (size_t i = 0; i < cached_form.field_count(); ++i) { 628 for (size_t i = 0; i < cached_form.field_count(); ++i) {
644 const AutofillField* field = cached_form.field(i); 629 const AutofillField* field = cached_form.field(i);
645 cached_fields[field->FieldSignature()] = field; 630 cached_fields[field->FieldSignatureAsStr()] = field;
646 } 631 }
647 632
648 for (AutofillField* field : *this) { 633 for (AutofillField* field : *this) {
649 std::map<std::string, const AutofillField*>::const_iterator 634 std::map<std::string, const AutofillField*>::const_iterator cached_field =
650 cached_field = cached_fields.find(field->FieldSignature()); 635 cached_fields.find(field->FieldSignatureAsStr());
651 if (cached_field != cached_fields.end()) { 636 if (cached_field != cached_fields.end()) {
652 if (field->form_control_type != "select-one" && 637 if (field->form_control_type != "select-one" &&
653 field->value == cached_field->second->value) { 638 field->value == cached_field->second->value) {
654 // From the perspective of learning user data, text fields containing 639 // From the perspective of learning user data, text fields containing
655 // default values are equivalent to empty fields. 640 // default values are equivalent to empty fields.
656 field->value = base::string16(); 641 field->value = base::string16();
657 } 642 }
658 643
659 // Transfer attributes of the cached AutofillField to the newly created 644 // Transfer attributes of the cached AutofillField to the newly created
660 // AutofillField. 645 // AutofillField.
(...skipping 10 matching lines...) Expand all
671 UpdateAutofillCount(); 656 UpdateAutofillCount();
672 657
673 // The form signature should match between query and upload requests to the 658 // The form signature should match between query and upload requests to the
674 // server. On many websites, form elements are dynamically added, removed, or 659 // server. On many websites, form elements are dynamically added, removed, or
675 // rearranged via JavaScript between page load and form submission, so we 660 // rearranged via JavaScript between page load and form submission, so we
676 // copy over the |form_signature_field_names_| corresponding to the query 661 // copy over the |form_signature_field_names_| corresponding to the query
677 // request. 662 // request.
678 DCHECK_EQ(cached_form.form_name_, form_name_); 663 DCHECK_EQ(cached_form.form_name_, form_name_);
679 DCHECK_EQ(cached_form.source_url_, source_url_); 664 DCHECK_EQ(cached_form.source_url_, source_url_);
680 DCHECK_EQ(cached_form.target_url_, target_url_); 665 DCHECK_EQ(cached_form.target_url_, target_url_);
681 form_signature_field_names_ = cached_form.form_signature_field_names_; 666 form_signature_ = cached_form.form_signature_;
682 } 667 }
683 668
684 void FormStructure::LogQualityMetrics(const base::TimeTicks& load_time, 669 void FormStructure::LogQualityMetrics(const base::TimeTicks& load_time,
685 const base::TimeTicks& interaction_time, 670 const base::TimeTicks& interaction_time,
686 const base::TimeTicks& submission_time, 671 const base::TimeTicks& submission_time,
687 rappor::RapporService* rappor_service, 672 rappor::RapporService* rappor_service,
688 bool did_show_suggestions, 673 bool did_show_suggestions,
689 bool observed_submission) const { 674 bool observed_submission) const {
690 size_t num_detected_field_types = 0; 675 size_t num_detected_field_types = 0;
691 size_t num_server_mismatches = 0; 676 size_t num_server_mismatches = 0;
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 } 1106 }
1122 1107
1123 bool FormStructure::operator!=(const FormData& form) const { 1108 bool FormStructure::operator!=(const FormData& form) const {
1124 return !operator==(form); 1109 return !operator==(form);
1125 } 1110 }
1126 1111
1127 void FormStructure::EncodeFormForQuery( 1112 void FormStructure::EncodeFormForQuery(
1128 AutofillQueryContents::Form* query_form) const { 1113 AutofillQueryContents::Form* query_form) const {
1129 DCHECK(!IsMalformed()); 1114 DCHECK(!IsMalformed());
1130 1115
1131 query_form->set_signature(FormSignature64Bit()); 1116 query_form->set_signature(form_signature());
1132 for (const AutofillField* field : fields_) { 1117 for (const AutofillField* field : fields_) {
1133 if (ShouldSkipField(*field)) 1118 if (ShouldSkipField(*field))
1134 continue; 1119 continue;
1135 1120
1136 AutofillQueryContents::Form::Field* added_field = query_form->add_field(); 1121 AutofillQueryContents::Form::Field* added_field = query_form->add_field();
1137 unsigned sig = 0;
1138 1122
1139 // The signature is a required field. If it can't be parsed, the proto would 1123 added_field->set_signature(field->GetFieldSignature());
1140 // not serialize.
1141 if (!base::StringToUint(field->FieldSignature(), &sig))
1142 continue;
1143 added_field->set_signature(sig);
1144 1124
1145 if (IsAutofillFieldMetadataEnabled()) { 1125 if (IsAutofillFieldMetadataEnabled()) {
1146 added_field->set_type(field->form_control_type); 1126 added_field->set_type(field->form_control_type);
1147 1127
1148 if (!field->name.empty()) 1128 if (!field->name.empty())
1149 added_field->set_name(base::UTF16ToUTF8(field->name)); 1129 added_field->set_name(base::UTF16ToUTF8(field->name));
1150 1130
1151 } 1131 }
1152 } 1132 }
1153 } 1133 }
(...skipping 15 matching lines...) Expand all
1169 AutofillUploadContents::Field* added_field = upload->add_field(); 1149 AutofillUploadContents::Field* added_field = upload->add_field();
1170 added_field->set_autofill_type(field_type); 1150 added_field->set_autofill_type(field_type);
1171 if (field->generation_type()) 1151 if (field->generation_type())
1172 added_field->set_generation_type(field->generation_type()); 1152 added_field->set_generation_type(field->generation_type());
1173 1153
1174 if (field->form_classifier_outcome()) { 1154 if (field->form_classifier_outcome()) {
1175 added_field->set_form_classifier_outcome( 1155 added_field->set_form_classifier_outcome(
1176 field->form_classifier_outcome()); 1156 field->form_classifier_outcome());
1177 } 1157 }
1178 1158
1179 unsigned sig = 0; 1159 added_field->set_signature(field->GetFieldSignature());
1180 // The signature is a required field. If it can't be parsed, the proto
1181 // would not serialize.
1182 if (!base::StringToUint(field->FieldSignature(), &sig))
1183 continue;
1184 added_field->set_signature(sig);
1185 1160
1186 if (IsAutofillFieldMetadataEnabled()) { 1161 if (IsAutofillFieldMetadataEnabled()) {
1187 added_field->set_type(field->form_control_type); 1162 added_field->set_type(field->form_control_type);
1188 1163
1189 if (!field->name.empty()) 1164 if (!field->name.empty())
1190 added_field->set_name(base::UTF16ToUTF8(field->name)); 1165 added_field->set_name(base::UTF16ToUTF8(field->name));
1191 1166
1192 if (!field->autocomplete_attribute.empty()) 1167 if (!field->autocomplete_attribute.empty())
1193 added_field->set_autocomplete(field->autocomplete_attribute); 1168 added_field->set_autocomplete(field->autocomplete_attribute);
1194 1169
1195 if (!field->css_classes.empty()) 1170 if (!field->css_classes.empty())
1196 added_field->set_css_classes(base::UTF16ToUTF8(field->css_classes)); 1171 added_field->set_css_classes(base::UTF16ToUTF8(field->css_classes));
1197 1172
1198 if (field->properties_mask) 1173 if (field->properties_mask)
1199 added_field->set_properties_mask(field->properties_mask); 1174 added_field->set_properties_mask(field->properties_mask);
1200 } 1175 }
1201 } 1176 }
1202 } 1177 }
1203 } 1178 }
1204 1179
1205 uint64_t FormStructure::Hash64Bit(const std::string& str) {
1206 std::string hash_bin = base::SHA1HashString(str);
1207 DCHECK_EQ(base::kSHA1Length, hash_bin.length());
1208
1209 uint64_t hash64 = (((static_cast<uint64_t>(hash_bin[0])) & 0xFF) << 56) |
1210 (((static_cast<uint64_t>(hash_bin[1])) & 0xFF) << 48) |
1211 (((static_cast<uint64_t>(hash_bin[2])) & 0xFF) << 40) |
1212 (((static_cast<uint64_t>(hash_bin[3])) & 0xFF) << 32) |
1213 (((static_cast<uint64_t>(hash_bin[4])) & 0xFF) << 24) |
1214 (((static_cast<uint64_t>(hash_bin[5])) & 0xFF) << 16) |
1215 (((static_cast<uint64_t>(hash_bin[6])) & 0xFF) << 8) |
1216 ((static_cast<uint64_t>(hash_bin[7])) & 0xFF);
1217
1218 return hash64;
1219 }
1220
1221 uint64_t FormStructure::FormSignature64Bit() const {
1222 std::string scheme(target_url_.scheme());
1223 std::string host(target_url_.host());
1224
1225 // If target host or scheme is empty, set scheme and host of source url.
1226 // This is done to match the Toolbar's behavior.
1227 if (scheme.empty() || host.empty()) {
1228 scheme = source_url_.scheme();
1229 host = source_url_.host();
1230 }
1231
1232 std::string form_string = scheme + "://" + host + "&" +
1233 base::UTF16ToUTF8(form_name_) +
1234 form_signature_field_names_;
1235
1236 return Hash64Bit(form_string);
1237 }
1238
1239 bool FormStructure::IsMalformed() const { 1180 bool FormStructure::IsMalformed() const {
1240 if (!field_count()) // Nothing to add. 1181 if (!field_count()) // Nothing to add.
1241 return true; 1182 return true;
1242 1183
1243 // Some badly formatted web sites repeat fields - limit number of fields to 1184 // Some badly formatted web sites repeat fields - limit number of fields to
1244 // 48, which is far larger than any valid form and proto still fits into 2K. 1185 // 48, which is far larger than any valid form and proto still fits into 2K.
1245 // Do not send requests for forms with more than this many fields, as they are 1186 // Do not send requests for forms with more than this many fields, as they are
1246 // near certainly not valid/auto-fillable. 1187 // near certainly not valid/auto-fillable.
1247 const size_t kMaxFieldsOnTheForm = 48; 1188 const size_t kMaxFieldsOnTheForm = 48;
1248 if (field_count() > kMaxFieldsOnTheForm) 1189 if (field_count() > kMaxFieldsOnTheForm)
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1381 filtered_strings[0].at(prefix_len)) { 1322 filtered_strings[0].at(prefix_len)) {
1382 // Mismatch found. 1323 // Mismatch found.
1383 return filtered_strings[i].substr(0, prefix_len); 1324 return filtered_strings[i].substr(0, prefix_len);
1384 } 1325 }
1385 } 1326 }
1386 } 1327 }
1387 return filtered_strings[0]; 1328 return filtered_strings[0];
1388 } 1329 }
1389 1330
1390 } // namespace autofill 1331 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/core/browser/form_structure.h ('k') | components/autofill/core/browser/form_structure_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698