| 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->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 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->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 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 |