| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/autofill/form_structure.h" | 5 #include "chrome/browser/autofill/form_structure.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/sha1.h" | 9 #include "base/sha1.h" |
| 10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 const char kClientVersion[] = "6.1.1715.1442/en (GGLL)"; | 34 const char kClientVersion[] = "6.1.1715.1442/en (GGLL)"; |
| 35 const char kXMLDeclaration[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; | 35 const char kXMLDeclaration[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; |
| 36 const char kXMLElementAutofillQuery[] = "autofillquery"; | 36 const char kXMLElementAutofillQuery[] = "autofillquery"; |
| 37 const char kXMLElementAutofillUpload[] = "autofillupload"; | 37 const char kXMLElementAutofillUpload[] = "autofillupload"; |
| 38 const char kXMLElementForm[] = "form"; | 38 const char kXMLElementForm[] = "form"; |
| 39 const char kXMLElementField[] = "field"; | 39 const char kXMLElementField[] = "field"; |
| 40 | 40 |
| 41 // The number of fillable fields necessary for a form to be fillable. | 41 // The number of fillable fields necessary for a form to be fillable. |
| 42 const size_t kRequiredFillableFields = 3; | 42 const size_t kRequiredFillableFields = 3; |
| 43 | 43 |
| 44 // Helper for |EncodeUploadRequest()| that creates a bit field corresponding to |
| 45 // |available_field_types| and returns the hex representation as a string. |
| 46 std::string EncodeFieldTypes(const FieldTypeSet& available_field_types) { |
| 47 // There are |MAX_VALID_FIELD_TYPE| different field types and 8 bits per byte, |
| 48 // so we need ceil(MAX_VALID_FIELD_TYPE / 8) bytes to encode the bit field. |
| 49 const size_t kNumBytes = (MAX_VALID_FIELD_TYPE + 0x7) / 8; |
| 50 |
| 51 // Pack the types in |available_field_types| into |bit_field|. |
| 52 std::vector<uint8> bit_field(kNumBytes, 0); |
| 53 for (FieldTypeSet::const_iterator field_type = available_field_types.begin(); |
| 54 field_type != available_field_types.end(); |
| 55 ++field_type) { |
| 56 // Set the appropriate bit in the field. The bit we set is the one |
| 57 // |field_type| % 8 from the left of the byte. |
| 58 const size_t byte = *field_type / 8; |
| 59 const size_t bit = 0x80 >> (*field_type % 8); |
| 60 DCHECK(byte < bit_field.size()); |
| 61 bit_field[byte] |= bit; |
| 62 } |
| 63 |
| 64 // Discard any trailing zeroes. |
| 65 // If there are no available types, we return the empty string. |
| 66 size_t data_end = bit_field.size(); |
| 67 for (; data_end > 0 && !bit_field[data_end - 1]; --data_end) { |
| 68 } |
| 69 |
| 70 // Print all meaningfull bytes into a string. |
| 71 std::string data_presence; |
| 72 data_presence.reserve(data_end * 2 + 1); |
| 73 for (size_t i = 0; i < data_end; ++i) { |
| 74 base::StringAppendF(&data_presence, "%02x", bit_field[i]); |
| 75 } |
| 76 |
| 77 return data_presence; |
| 78 } |
| 79 |
| 44 } // namespace | 80 } // namespace |
| 45 | 81 |
| 46 FormStructure::FormStructure(const FormData& form) | 82 FormStructure::FormStructure(const FormData& form) |
| 47 : form_name_(form.name), | 83 : form_name_(form.name), |
| 48 source_url_(form.origin), | 84 source_url_(form.origin), |
| 49 target_url_(form.action), | 85 target_url_(form.action), |
| 50 autofill_count_(0) { | 86 autofill_count_(0) { |
| 51 // Copy the form fields. | 87 // Copy the form fields. |
| 52 std::vector<webkit_glue::FormField>::const_iterator field; | 88 std::vector<webkit_glue::FormField>::const_iterator field; |
| 53 for (field = form.fields.begin(); | 89 for (field = form.fields.begin(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 heuristic_autofill_type = iter->second; | 128 heuristic_autofill_type = iter->second; |
| 93 ++autofill_count_; | 129 ++autofill_count_; |
| 94 } | 130 } |
| 95 | 131 |
| 96 field->set_heuristic_type(heuristic_autofill_type); | 132 field->set_heuristic_type(heuristic_autofill_type); |
| 97 | 133 |
| 98 AutofillType autofill_type(field->type()); | 134 AutofillType autofill_type(field->type()); |
| 99 } | 135 } |
| 100 } | 136 } |
| 101 | 137 |
| 102 bool FormStructure::EncodeUploadRequest(bool autofill_used, | 138 bool FormStructure::EncodeUploadRequest( |
| 103 std::string* encoded_xml) const { | 139 const FieldTypeSet& available_field_types, |
| 104 DCHECK(encoded_xml); | 140 bool form_was_autofilled, |
| 105 encoded_xml->clear(); | 141 std::string* encoded_xml) const { |
| 106 bool autofillable = ShouldBeParsed(true); | 142 if (!ShouldBeParsed(true)) { |
| 107 DCHECK(autofillable); // Caller should've checked for search pages. | 143 NOTREACHED(); // Caller should've checked for search pages. |
| 108 if (!autofillable) | |
| 109 return false; | 144 return false; |
| 145 } |
| 146 |
| 147 // Verify that |available_field_types| agrees with the possible field types we |
| 148 // are uploading. |
| 149 for (std::vector<AutofillField*>::const_iterator field = begin(); |
| 150 field != end(); |
| 151 ++field) { |
| 152 for (FieldTypeSet::const_iterator type = (*field)->possible_types().begin(); |
| 153 type != (*field)->possible_types().end(); |
| 154 ++type) { |
| 155 DCHECK(*type == UNKNOWN_TYPE || |
| 156 *type == EMPTY_TYPE || |
| 157 available_field_types.count(*type)); |
| 158 } |
| 159 } |
| 110 | 160 |
| 111 // Set up the <autofillupload> element and its attributes. | 161 // Set up the <autofillupload> element and its attributes. |
| 112 buzz::XmlElement autofill_request_xml( | 162 buzz::XmlElement autofill_request_xml( |
| 113 (buzz::QName(kXMLElementAutofillUpload))); | 163 (buzz::QName(kXMLElementAutofillUpload))); |
| 114 autofill_request_xml.SetAttr(buzz::QName(kAttributeClientVersion), | 164 autofill_request_xml.SetAttr(buzz::QName(kAttributeClientVersion), |
| 115 kClientVersion); | 165 kClientVersion); |
| 116 autofill_request_xml.SetAttr(buzz::QName(kAttributeFormSignature), | 166 autofill_request_xml.SetAttr(buzz::QName(kAttributeFormSignature), |
| 117 FormSignature()); | 167 FormSignature()); |
| 118 autofill_request_xml.SetAttr(buzz::QName(kAttributeAutofillUsed), | 168 autofill_request_xml.SetAttr(buzz::QName(kAttributeAutofillUsed), |
| 119 autofill_used ? "true" : "false"); | 169 form_was_autofilled ? "true" : "false"); |
| 120 autofill_request_xml.SetAttr(buzz::QName(kAttributeDataPresent), | 170 autofill_request_xml.SetAttr(buzz::QName(kAttributeDataPresent), |
| 121 ConvertPresenceBitsToString().c_str()); | 171 EncodeFieldTypes(available_field_types).c_str()); |
| 122 | 172 |
| 123 if (!EncodeFormRequest(FormStructure::UPLOAD, &autofill_request_xml)) | 173 if (!EncodeFormRequest(FormStructure::UPLOAD, &autofill_request_xml)) |
| 124 return false; // Malformed form, skip it. | 174 return false; // Malformed form, skip it. |
| 125 | 175 |
| 126 // Obtain the XML structure as a string. | 176 // Obtain the XML structure as a string. |
| 177 encoded_xml->clear(); |
| 127 *encoded_xml = kXMLDeclaration; | 178 *encoded_xml = kXMLDeclaration; |
| 128 *encoded_xml += autofill_request_xml.Str().c_str(); | 179 *encoded_xml += autofill_request_xml.Str().c_str(); |
| 129 | 180 |
| 130 return true; | 181 return true; |
| 131 } | 182 } |
| 132 | 183 |
| 133 // static | 184 // static |
| 134 bool FormStructure::EncodeQueryRequest(const ScopedVector<FormStructure>& forms, | 185 bool FormStructure::EncodeQueryRequest(const ScopedVector<FormStructure>& forms, |
| 135 std::vector<std::string>* encoded_signatures, | 186 std::vector<std::string>* encoded_signatures, |
| 136 std::string* encoded_xml) { | 187 std::string* encoded_xml) { |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 } else { | 584 } else { |
| 534 buzz::XmlElement *field_element = new buzz::XmlElement( | 585 buzz::XmlElement *field_element = new buzz::XmlElement( |
| 535 buzz::QName(kXMLElementField)); | 586 buzz::QName(kXMLElementField)); |
| 536 field_element->SetAttr(buzz::QName(kAttributeSignature), | 587 field_element->SetAttr(buzz::QName(kAttributeSignature), |
| 537 field->FieldSignature()); | 588 field->FieldSignature()); |
| 538 encompassing_xml_element->AddElement(field_element); | 589 encompassing_xml_element->AddElement(field_element); |
| 539 } | 590 } |
| 540 } | 591 } |
| 541 return true; | 592 return true; |
| 542 } | 593 } |
| 543 | |
| 544 std::string FormStructure::ConvertPresenceBitsToString() const { | |
| 545 std::vector<uint8> presence_bitfield; | |
| 546 // Determine all of the field types that were autofilled. Pack bits into | |
| 547 // |presence_bitfield|. The necessary size for |presence_bitfield| is | |
| 548 // ceil((MAX_VALID_FIELD_TYPE + 7) / 8) bytes (uint8). | |
| 549 presence_bitfield.resize((MAX_VALID_FIELD_TYPE + 0x7) / 8); | |
| 550 for (size_t i = 0; i < presence_bitfield.size(); ++i) | |
| 551 presence_bitfield[i] = 0; | |
| 552 | |
| 553 for (size_t i = 0; i < field_count(); ++i) { | |
| 554 const AutofillField* field = fields_[i]; | |
| 555 FieldTypeSet types = field->possible_types(); | |
| 556 // |types| could be empty in unit-tests only. | |
| 557 for (FieldTypeSet::iterator field_type = types.begin(); | |
| 558 field_type != types.end(); ++field_type) { | |
| 559 DCHECK(presence_bitfield.size() > (static_cast<size_t>(*field_type) / 8)); | |
| 560 // Set bit in the bitfield: byte |field_type| / 8, bit in byte | |
| 561 // |field_type| % 8 from the left. | |
| 562 presence_bitfield[*field_type / 8] |= (0x80 >> (*field_type % 8)); | |
| 563 } | |
| 564 } | |
| 565 | |
| 566 std::string data_presence; | |
| 567 data_presence.reserve(presence_bitfield.size() * 2 + 1); | |
| 568 | |
| 569 // Skip trailing zeroes. If all mask is 0 - return empty string. | |
| 570 size_t data_end = presence_bitfield.size(); | |
| 571 for (; data_end > 0 && !presence_bitfield[data_end - 1]; --data_end) { | |
| 572 } | |
| 573 | |
| 574 // Print all meaningfull bytes into the string. | |
| 575 for (size_t i = 0; i < data_end; ++i) { | |
| 576 base::StringAppendF(&data_presence, "%02x", presence_bitfield[i]); | |
| 577 } | |
| 578 | |
| 579 return data_presence; | |
| 580 } | |
| 581 | |
| OLD | NEW |