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

Side by Side Diff: chrome/browser/autofill/form_structure.cc

Issue 6931029: Set datapresent string to contain precisely those field types available in stored Autofill data. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Signed and delivered Created 9 years, 7 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 | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/browser/autofill/form_structure.h ('k') | chrome/browser/autofill/form_structure_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698