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/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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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->FieldSignature()); |
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 Loading... |
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->FieldSignature()); |
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 Loading... |
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 |
OLD | NEW |