| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 | 106 |
| 107 bool FormStructure::EncodeUploadRequest(bool auto_fill_used, | 107 bool FormStructure::EncodeUploadRequest(bool auto_fill_used, |
| 108 std::string* encoded_xml) const { | 108 std::string* encoded_xml) const { |
| 109 DCHECK(encoded_xml); | 109 DCHECK(encoded_xml); |
| 110 encoded_xml->clear(); | 110 encoded_xml->clear(); |
| 111 bool auto_fillable = IsAutoFillable(false); | 111 bool auto_fillable = IsAutoFillable(false); |
| 112 DCHECK(auto_fillable); // Caller should've checked for search pages. | 112 DCHECK(auto_fillable); // Caller should've checked for search pages. |
| 113 if (!auto_fillable) | 113 if (!auto_fillable) |
| 114 return false; | 114 return false; |
| 115 | 115 |
| 116 buzz::XmlElement autofill_request_xml(buzz::QName("autofillupload")); | 116 buzz::XmlElement autofil_request_xml(buzz::QName("autofillupload")); |
| 117 | 117 |
| 118 // Attributes for the <autofillupload> element. | 118 // Attributes for the <autofillupload> element. |
| 119 // | 119 // |
| 120 // TODO(jhawkins): Work with toolbar devs to make a spec for autofill clients. | 120 // TODO(jhawkins): Work with toolbar devs to make a spec for autofill clients. |
| 121 // For now these values are hacked from the toolbar code. | 121 // For now these values are hacked from the toolbar code. |
| 122 autofill_request_xml.SetAttr(buzz::QName(kAttributeClientVersion), | 122 autofil_request_xml.SetAttr(buzz::QName(kAttributeClientVersion), |
| 123 "6.1.1715.1442/en (GGLL)"); | 123 "6.1.1715.1442/en (GGLL)"); |
| 124 | 124 |
| 125 autofill_request_xml.SetAttr(buzz::QName(kAttributeFormSignature), | 125 autofil_request_xml.SetAttr(buzz::QName(kAttributeFormSignature), |
| 126 FormSignature()); | 126 FormSignature()); |
| 127 | 127 |
| 128 autofill_request_xml.SetAttr(buzz::QName(kAttributeAutoFillUsed), | 128 autofil_request_xml.SetAttr(buzz::QName(kAttributeAutoFillUsed), |
| 129 auto_fill_used ? "true" : "false"); | 129 auto_fill_used ? "true" : "false"); |
| 130 | 130 |
| 131 autofill_request_xml.SetAttr(buzz::QName(kAttributeDataPresent), | 131 // TODO(jhawkins): Hook this up to the personal data manager. |
| 132 ConvertPresenceBitsToString().c_str()); | 132 // personaldata_manager_->GetDataPresent(); |
| 133 autofil_request_xml.SetAttr(buzz::QName(kAttributeDataPresent), ""); |
| 133 | 134 |
| 134 if (!EncodeFormRequest(FormStructure::UPLOAD, &autofill_request_xml)) | 135 if (!EncodeFormRequest(FormStructure::UPLOAD, &autofil_request_xml)) |
| 135 return false; // Malformed form, skip it. | 136 return false; // Malformed form, skip it. |
| 136 | 137 |
| 137 // Obtain the XML structure as a string. | 138 // Obtain the XML structure as a string. |
| 138 *encoded_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; | 139 *encoded_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; |
| 139 *encoded_xml += autofill_request_xml.Str().c_str(); | 140 *encoded_xml += autofil_request_xml.Str().c_str(); |
| 140 | 141 |
| 141 return true; | 142 return true; |
| 142 } | 143 } |
| 143 | 144 |
| 144 // static | 145 // static |
| 145 bool FormStructure::EncodeQueryRequest(const ScopedVector<FormStructure>& forms, | 146 bool FormStructure::EncodeQueryRequest(const ScopedVector<FormStructure>& forms, |
| 146 std::vector<std::string>* encoded_signatures, | 147 std::vector<std::string>* encoded_signatures, |
| 147 std::string* encoded_xml) { | 148 std::string* encoded_xml) { |
| 148 DCHECK(encoded_signatures); | 149 DCHECK(encoded_signatures); |
| 149 DCHECK(encoded_xml); | 150 DCHECK(encoded_xml); |
| 150 encoded_xml->clear(); | 151 encoded_xml->clear(); |
| 151 encoded_signatures->clear(); | 152 encoded_signatures->clear(); |
| 152 encoded_signatures->reserve(forms.size()); | 153 encoded_signatures->reserve(forms.size()); |
| 153 buzz::XmlElement autofill_request_xml(buzz::QName("autofillquery")); | 154 buzz::XmlElement autofil_request_xml(buzz::QName("autofillquery")); |
| 154 // Attributes for the <autofillquery> element. | 155 // Attributes for the <autofillquery> element. |
| 155 // | 156 // |
| 156 // TODO(jhawkins): Work with toolbar devs to make a spec for autofill clients. | 157 // TODO(jhawkins): Work with toolbar devs to make a spec for autofill clients. |
| 157 // For now these values are hacked from the toolbar code. | 158 // For now these values are hacked from the toolbar code. |
| 158 autofill_request_xml.SetAttr(buzz::QName(kAttributeClientVersion), | 159 autofil_request_xml.SetAttr(buzz::QName(kAttributeClientVersion), |
| 159 "6.1.1715.1442/en (GGLL)"); | 160 "6.1.1715.1442/en (GGLL)"); |
| 160 // Some badly formatted web sites repeat forms - detect that and encode only | 161 // Some badly formatted web sites repeat forms - detect that and encode only |
| 161 // one form as returned data would be the same for all the repeated forms. | 162 // one form as returned data would be the same for all the repeated forms. |
| 162 std::set<std::string> processed_forms; | 163 std::set<std::string> processed_forms; |
| 163 for (ScopedVector<FormStructure>::const_iterator it = forms.begin(); | 164 for (ScopedVector<FormStructure>::const_iterator it = forms.begin(); |
| 164 it != forms.end(); | 165 it != forms.end(); |
| 165 ++it) { | 166 ++it) { |
| 166 std::string signature((*it)->FormSignature()); | 167 std::string signature((*it)->FormSignature()); |
| 167 if (processed_forms.find(signature) != processed_forms.end()) | 168 if (processed_forms.find(signature) != processed_forms.end()) |
| 168 continue; | 169 continue; |
| 169 processed_forms.insert(signature); | 170 processed_forms.insert(signature); |
| 170 scoped_ptr<buzz::XmlElement> encompassing_xml_element( | 171 scoped_ptr<buzz::XmlElement> encompassing_xml_element( |
| 171 new buzz::XmlElement(buzz::QName("form"))); | 172 new buzz::XmlElement(buzz::QName("form"))); |
| 172 encompassing_xml_element->SetAttr(buzz::QName(kAttributeSignature), | 173 encompassing_xml_element->SetAttr(buzz::QName(kAttributeSignature), |
| 173 signature); | 174 signature); |
| 174 | 175 |
| 175 if (!(*it)->EncodeFormRequest(FormStructure::QUERY, | 176 if (!(*it)->EncodeFormRequest(FormStructure::QUERY, |
| 176 encompassing_xml_element.get())) | 177 encompassing_xml_element.get())) |
| 177 continue; // Malformed form, skip it. | 178 continue; // Malformed form, skip it. |
| 178 | 179 |
| 179 autofill_request_xml.AddElement(encompassing_xml_element.release()); | 180 autofil_request_xml.AddElement(encompassing_xml_element.release()); |
| 180 encoded_signatures->push_back(signature); | 181 encoded_signatures->push_back(signature); |
| 181 } | 182 } |
| 182 | 183 |
| 183 if (!encoded_signatures->size()) | 184 if (!encoded_signatures->size()) |
| 184 return false; | 185 return false; |
| 185 | 186 |
| 186 // Obtain the XML structure as a string. | 187 // Obtain the XML structure as a string. |
| 187 *encoded_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; | 188 *encoded_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; |
| 188 *encoded_xml += autofill_request_xml.Str().c_str(); | 189 *encoded_xml += autofil_request_xml.Str().c_str(); |
| 189 | 190 |
| 190 return true; | 191 return true; |
| 191 } | 192 } |
| 192 | 193 |
| 193 // static | 194 // static |
| 194 void FormStructure::ParseQueryResponse(const std::string& response_xml, | 195 void FormStructure::ParseQueryResponse(const std::string& response_xml, |
| 195 const std::vector<FormStructure*>& forms, | 196 const std::vector<FormStructure*>& forms, |
| 196 UploadRequired* upload_required, | 197 UploadRequired* upload_required, |
| 197 const AutoFillMetrics& metric_logger) { | 198 const AutoFillMetrics& metric_logger) { |
| 198 metric_logger.Log(AutoFillMetrics::QUERY_RESPONSE_RECEIVED); | 199 metric_logger.Log(AutoFillMetrics::QUERY_RESPONSE_RECEIVED); |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 if (field_count() > kMaxFieldsOnTheForm) { | 406 if (field_count() > kMaxFieldsOnTheForm) { |
| 406 // This is not a valid form, most certainly. Do not send request for the | 407 // This is not a valid form, most certainly. Do not send request for the |
| 407 // wrongly formatted forms. | 408 // wrongly formatted forms. |
| 408 return false; | 409 return false; |
| 409 } | 410 } |
| 410 // Add the child nodes for the form fields. | 411 // Add the child nodes for the form fields. |
| 411 for (size_t index = 0; index < field_count(); ++index) { | 412 for (size_t index = 0; index < field_count(); ++index) { |
| 412 const AutoFillField* field = fields_[index]; | 413 const AutoFillField* field = fields_[index]; |
| 413 if (request_type == FormStructure::UPLOAD) { | 414 if (request_type == FormStructure::UPLOAD) { |
| 414 FieldTypeSet types = field->possible_types(); | 415 FieldTypeSet types = field->possible_types(); |
| 415 DCHECK(!types.empty()); | 416 for (FieldTypeSet::const_iterator type = types.begin(); |
| 416 for (FieldTypeSet::iterator field_type = types.begin(); | 417 type != types.end(); type++) { |
| 417 field_type != types.end(); ++field_type) { | |
| 418 buzz::XmlElement *field_element = new buzz::XmlElement( | 418 buzz::XmlElement *field_element = new buzz::XmlElement( |
| 419 buzz::QName(kXMLElementField)); | 419 buzz::QName(kXMLElementField)); |
| 420 | 420 |
| 421 field_element->SetAttr(buzz::QName(kAttributeSignature), | 421 field_element->SetAttr(buzz::QName(kAttributeSignature), |
| 422 field->FieldSignature()); | 422 field->FieldSignature()); |
| 423 field_element->SetAttr(buzz::QName(kAttributeAutoFillType), | 423 field_element->SetAttr(buzz::QName(kAttributeAutoFillType), |
| 424 base::IntToString(*field_type)); | 424 base::IntToString(*type)); |
| 425 encompassing_xml_element->AddElement(field_element); | 425 encompassing_xml_element->AddElement(field_element); |
| 426 } | 426 } |
| 427 } else { | 427 } else { |
| 428 buzz::XmlElement *field_element = new buzz::XmlElement( | 428 buzz::XmlElement *field_element = new buzz::XmlElement( |
| 429 buzz::QName(kXMLElementField)); | 429 buzz::QName(kXMLElementField)); |
| 430 field_element->SetAttr(buzz::QName(kAttributeSignature), | 430 field_element->SetAttr(buzz::QName(kAttributeSignature), |
| 431 field->FieldSignature()); | 431 field->FieldSignature()); |
| 432 encompassing_xml_element->AddElement(field_element); | 432 encompassing_xml_element->AddElement(field_element); |
| 433 } | 433 } |
| 434 } | 434 } |
| 435 return true; | 435 return true; |
| 436 } | 436 } |
| 437 | |
| 438 std::string FormStructure::ConvertPresenceBitsToString() const { | |
| 439 std::vector<uint8> presence_bitfield; | |
| 440 // Determine all of the field types that were autofilled. Pack bits into | |
| 441 // |presence_bitfield|. The necessary size for |presence_bitfield| is | |
| 442 // ceil((MAX_VALID_FIELD_TYPE + 7) / 8) bytes (uint8). | |
| 443 presence_bitfield.resize((MAX_VALID_FIELD_TYPE + 0x7) / 8); | |
| 444 for (size_t i = 0; i < presence_bitfield.size(); ++i) | |
| 445 presence_bitfield[i] = 0; | |
| 446 | |
| 447 for (size_t i = 0; i < field_count(); ++i) { | |
| 448 const AutoFillField* field = fields_[i]; | |
| 449 FieldTypeSet types = field->possible_types(); | |
| 450 DCHECK(!types.empty()); | |
| 451 for (FieldTypeSet::iterator field_type = types.begin(); | |
| 452 field_type != types.end(); ++field_type) { | |
| 453 DCHECK(presence_bitfield.size() > (static_cast<size_t>(*field_type) / 8)); | |
| 454 // Set bit in the bitfield: byte |field_type| / 8, bit in byte | |
| 455 // |field_type| % 8 from the left. | |
| 456 presence_bitfield[*field_type / 8] |= (0x80 >> (*field_type % 8)); | |
| 457 } | |
| 458 } | |
| 459 | |
| 460 std::string data_presence; | |
| 461 data_presence.reserve(presence_bitfield.size() * 2 + 1); | |
| 462 | |
| 463 // Skip trailing zeroes. If all mask is 0 - return empty string. | |
| 464 size_t data_end = presence_bitfield.size(); | |
| 465 for (; data_end > 0 && !presence_bitfield[data_end - 1]; --data_end) { | |
| 466 } | |
| 467 | |
| 468 // Print all meaningfull bytes into the string. | |
| 469 for (size_t i = 0; i < data_end; ++i) { | |
| 470 base::StringAppendF(&data_presence, "%02x", presence_bitfield[i]); | |
| 471 } | |
| 472 | |
| 473 return data_presence; | |
| 474 } | |
| 475 | |
| OLD | NEW |