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

Side by Side Diff: components/autofill/core/browser/form_structure.cc

Issue 1477733003: Replace xmllite with libxml in autofill (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@556433_remove_dead_code
Patch Set: Just rebased Created 5 years 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
OLDNEW
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 <map>
7 #include <utility> 8 #include <utility>
8 9
9 #include "base/basictypes.h" 10 #include "base/basictypes.h"
10 #include "base/command_line.h" 11 #include "base/command_line.h"
11 #include "base/i18n/case_conversion.h" 12 #include "base/i18n/case_conversion.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_ptr.h"
14 #include "base/metrics/field_trial.h" 15 #include "base/metrics/field_trial.h"
15 #include "base/sha1.h" 16 #include "base/sha1.h"
16 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_split.h" 18 #include "base/strings/string_split.h"
18 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
19 #include "base/strings/stringprintf.h" 20 #include "base/strings/stringprintf.h"
20 #include "base/strings/utf_string_conversions.h" 21 #include "base/strings/utf_string_conversions.h"
21 #include "base/time/time.h" 22 #include "base/time/time.h"
22 #include "components/autofill/core/browser/autofill_metrics.h" 23 #include "components/autofill/core/browser/autofill_metrics.h"
24 #include "components/autofill/core/browser/autofill_server_field_info.h"
23 #include "components/autofill/core/browser/autofill_type.h" 25 #include "components/autofill/core/browser/autofill_type.h"
24 #include "components/autofill/core/browser/autofill_xml_parser.h" 26 #include "components/autofill/core/browser/autofill_xml_parser.h"
25 #include "components/autofill/core/browser/field_types.h" 27 #include "components/autofill/core/browser/field_types.h"
26 #include "components/autofill/core/browser/form_field.h" 28 #include "components/autofill/core/browser/form_field.h"
27 #include "components/autofill/core/common/autofill_constants.h" 29 #include "components/autofill/core/common/autofill_constants.h"
28 #include "components/autofill/core/common/form_data.h" 30 #include "components/autofill/core/common/form_data.h"
29 #include "components/autofill/core/common/form_data_predictions.h" 31 #include "components/autofill/core/common/form_data_predictions.h"
30 #include "components/autofill/core/common/form_field_data.h" 32 #include "components/autofill/core/common/form_field_data.h"
31 #include "components/autofill/core/common/form_field_data_predictions.h" 33 #include "components/autofill/core/common/form_field_data_predictions.h"
32 #include "components/rappor/rappor_service.h" 34 #include "components/rappor/rappor_service.h"
33 #include "components/rappor/rappor_utils.h" 35 #include "components/rappor/rappor_utils.h"
36 #include "third_party/libxml/chromium/libxml_utils.h"
34 #include "third_party/re2/re2/re2.h" 37 #include "third_party/re2/re2/re2.h"
35 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
36 38
37 namespace autofill { 39 namespace autofill {
38 namespace { 40 namespace {
39 41
40 // XML elements and attributes. 42 // XML elements and attributes.
41 const char kAttributeAutofillUsed[] = "autofillused"; 43 const char kAttributeAutofillUsed[] = "autofillused";
42 const char kAttributeAutofillType[] = "autofilltype"; 44 const char kAttributeAutofillType[] = "autofilltype";
43 const char kAttributeClientVersion[] = "clientversion"; 45 const char kAttributeClientVersion[] = "clientversion";
44 const char kAttributeDataPresent[] = "datapresent"; 46 const char kAttributeDataPresent[] = "datapresent";
45 const char kAttributeFieldID[] = "fieldid"; 47 const char kAttributeFieldID[] = "fieldid";
46 const char kAttributeFieldType[] = "fieldtype"; 48 const char kAttributeFieldType[] = "fieldtype";
47 const char kAttributeFieldLabel[] = "label"; 49 const char kAttributeFieldLabel[] = "label";
48 const char kAttributeFormSignature[] = "formsignature"; 50 const char kAttributeFormSignature[] = "formsignature";
49 const char kAttributeFormActionHostSignature[] = "actionsignature"; 51 const char kAttributeFormActionHostSignature[] = "actionsignature";
50 const char kAttributeFormName[] = "formname"; 52 const char kAttributeFormName[] = "formname";
51 const char kAttributeName[] = "name"; 53 const char kAttributeName[] = "name";
52 const char kAttributeSignature[] = "signature"; 54 const char kAttributeSignature[] = "signature";
53 const char kAttributeControlType[] = "type"; 55 const char kAttributeControlType[] = "type";
54 const char kAttributeAutocomplete[] = "autocomplete"; 56 const char kAttributeAutocomplete[] = "autocomplete";
55 const char kAttributeLoginFormSignature[] = "loginformsignature"; 57 const char kAttributeLoginFormSignature[] = "loginformsignature";
56 const char kClientVersion[] = "6.1.1715.1442/en (GGLL)"; 58 const char kClientVersion[] = "6.1.1715.1442/en (GGLL)";
57 const char kXMLDeclaration[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
58 const char kXMLElementAutofillQuery[] = "autofillquery"; 59 const char kXMLElementAutofillQuery[] = "autofillquery";
59 const char kXMLElementAutofillUpload[] = "autofillupload"; 60 const char kXMLElementAutofillUpload[] = "autofillupload";
60 const char kXMLElementFieldAssignments[] = "fieldassignments"; 61 const char kXMLElementFieldAssignments[] = "fieldassignments";
61 const char kXMLElementField[] = "field"; 62 const char kXMLElementField[] = "field";
62 const char kXMLElementFields[] = "fields"; 63 const char kXMLElementFields[] = "fields";
63 const char kXMLElementForm[] = "form"; 64 const char kXMLElementForm[] = "form";
64 const char kBillingMode[] = "billing"; 65 const char kBillingMode[] = "billing";
65 const char kShippingMode[] = "shipping"; 66 const char kShippingMode[] = "shipping";
66 67
67 // Strip away >= 5 consecutive digits. 68 // Strip away >= 5 consecutive digits.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 // Print all meaningfull bytes into a string. 109 // Print all meaningfull bytes into a string.
109 std::string data_presence; 110 std::string data_presence;
110 data_presence.reserve(data_end * 2 + 1); 111 data_presence.reserve(data_end * 2 + 1);
111 for (size_t i = 0; i < data_end; ++i) { 112 for (size_t i = 0; i < data_end; ++i) {
112 base::StringAppendF(&data_presence, "%02x", bit_field[i]); 113 base::StringAppendF(&data_presence, "%02x", bit_field[i]);
113 } 114 }
114 115
115 return data_presence; 116 return data_presence;
116 } 117 }
117 118
118 // Helper for |EncodeFormRequest()| and |EncodeFieldForUpload| that returns an 119 // Assumes that |xml_writer| has just started an element with name
119 // XmlElement for the given field in query xml, and also add it to the parent 120 // |kXMLElementField|, and adds some field attributes based on |field|. Returns
120 // XmlElement. 121 // true on success, false on failure.
121 buzz::XmlElement* EncodeFieldForQuery(const AutofillField& field, 122 bool EncodeFieldForQuery(const AutofillField& field, XmlWriter* xml_writer) {
122 buzz::XmlElement* parent) { 123 if (!xml_writer->AddAttribute(kAttributeSignature, field.FieldSignature()))
123 buzz::XmlElement* field_element = new buzz::XmlElement( 124 return false;
124 buzz::QName(kXMLElementField));
125 field_element->SetAttr(buzz::QName(kAttributeSignature),
126 field.FieldSignature());
127 if (IsAutofillFieldMetadataEnabled()) { 125 if (IsAutofillFieldMetadataEnabled()) {
128 if (!field.name.empty()) { 126 if (!field.name.empty()) {
129 field_element->SetAttr(buzz::QName(kAttributeName), 127 if (!xml_writer->AddAttribute(kAttributeName,
130 base::UTF16ToUTF8(field.name)); 128 base::UTF16ToUTF8(field.name)))
129 return false;
131 } 130 }
132 field_element->SetAttr(buzz::QName(kAttributeControlType), 131 if (!xml_writer->AddAttribute(kAttributeControlType,
133 field.form_control_type); 132 field.form_control_type))
133 return false;
134 if (!field.label.empty()) { 134 if (!field.label.empty()) {
135 std::string truncated; 135 std::string truncated;
136 base::TruncateUTF8ToByteSize(base::UTF16ToUTF8(field.label), 136 base::TruncateUTF8ToByteSize(base::UTF16ToUTF8(field.label),
137 kMaxFieldLabelNumChars, &truncated); 137 kMaxFieldLabelNumChars, &truncated);
138 field_element->SetAttr(buzz::QName(kAttributeFieldLabel), truncated); 138 if (!xml_writer->AddAttribute(kAttributeFieldLabel, truncated))
139 return false;
139 } 140 }
140 } 141 }
141 parent->AddElement(field_element); 142 return true;
142 return field_element;
143 } 143 }
144 144
145 // Helper for |EncodeFormRequest()| that creates XmlElements for the given field 145 // Uses |xml_writer| to write one tag named |kXMLElementField| for each item in
146 // in upload xml, and also add them to the parent XmlElement. 146 // |field.possible_types()|, and adds some field attributes based on |field|.
147 void EncodeFieldForUpload(const AutofillField& field, 147 // Returns true on success, false on failure.
148 buzz::XmlElement* parent) { 148 bool EncodeFieldForUpload(const AutofillField& field, XmlWriter* xml_writer) {
149 // Don't upload checkable fields. 149 // Don't upload checkable fields.
150 if (field.is_checkable) 150 if (field.is_checkable)
151 return; 151 return true;
152 152
153 ServerFieldTypeSet types = field.possible_types(); 153 const ServerFieldTypeSet& types = field.possible_types();
154 // |types| could be empty in unit-tests only.
155 for (const auto& field_type : types) { 154 for (const auto& field_type : types) {
156 // We use the same field elements as the query and add a few more below. 155 if (!xml_writer->StartElement(kXMLElementField))
157 buzz::XmlElement* field_element = EncodeFieldForQuery(field, parent); 156 return false;
157 // Add the same field elements as the query and a few more below.
158 if (!EncodeFieldForQuery(field, xml_writer))
159 return false;
158 160
159 if (IsAutofillFieldMetadataEnabled() && 161 if (IsAutofillFieldMetadataEnabled() &&
160 !field.autocomplete_attribute.empty()) { 162 !field.autocomplete_attribute.empty()) {
161 field_element->SetAttr(buzz::QName(kAttributeAutocomplete), 163 if (!xml_writer->AddAttribute(kAttributeAutocomplete,
162 field.autocomplete_attribute); 164 field.autocomplete_attribute))
165 return false;
163 } 166 }
164 167
165 field_element->SetAttr(buzz::QName(kAttributeAutofillType), 168 if (!xml_writer->AddAttribute(kAttributeAutofillType,
166 base::IntToString(field_type)); 169 base::IntToString(field_type)))
170 return false;
171 if (!xml_writer->EndElement())
172 return false;
167 } 173 }
174 return true;
168 } 175 }
169 176
170 // Helper for |EncodeFormRequest()| that creates XmlElements for the given field 177 // Uses |xml_writer| to write one tag named |kXMLElementFields| for each item in
171 // in field assignments xml, and also add them to the parent XmlElement. 178 // |field.possible_types()|, and adds some field attributes based on |field|.
172 void EncodeFieldForFieldAssignments(const AutofillField& field, 179 // Returns true on success, false on failure.
173 buzz::XmlElement* parent) { 180 bool EncodeFieldForFieldAssignments(const AutofillField& field,
174 ServerFieldTypeSet types = field.possible_types(); 181 XmlWriter* xml_writer) {
182 const ServerFieldTypeSet& types = field.possible_types();
175 for (const auto& field_type : types) { 183 for (const auto& field_type : types) {
176 buzz::XmlElement *field_element = new buzz::XmlElement( 184 if (!xml_writer->StartElement(kXMLElementFields))
177 buzz::QName(kXMLElementFields)); 185 return false;
178 186
179 field_element->SetAttr(buzz::QName(kAttributeFieldID), 187 if (!xml_writer->AddAttribute(kAttributeFieldID, field.FieldSignature()))
180 field.FieldSignature()); 188 return false;
181 field_element->SetAttr(buzz::QName(kAttributeFieldType), 189 if (!xml_writer->AddAttribute(kAttributeFieldType,
182 base::IntToString(field_type)); 190 base::IntToString(field_type)))
183 field_element->SetAttr(buzz::QName(kAttributeName), 191 return false;
184 base::UTF16ToUTF8(field.name)); 192 if (!xml_writer->AddAttribute(kAttributeName,
185 parent->AddElement(field_element); 193 base::UTF16ToUTF8(field.name)))
194 return false;
195 if (!xml_writer->EndElement())
196 return false;
186 } 197 }
198 return true;
187 } 199 }
188 200
189 // Returns |true| iff the |token| is a type hint for a contact field, as 201 // Returns |true| iff the |token| is a type hint for a contact field, as
190 // specified in the implementation section of http://is.gd/whatwg_autocomplete 202 // specified in the implementation section of http://is.gd/whatwg_autocomplete
191 // Note that "fax" and "pager" are intentionally ignored, as Chrome does not 203 // Note that "fax" and "pager" are intentionally ignored, as Chrome does not
192 // support filling either type of information. 204 // support filling either type of information.
193 bool IsContactTypeHint(const std::string& token) { 205 bool IsContactTypeHint(const std::string& token) {
194 return token == "home" || token == "work" || token == "mobile"; 206 return token == "home" || token == "work" || token == "mobile";
195 } 207 }
196 208
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 AutofillMetrics::FILLABLE_FORM_CONTAINS_TYPE_HINTS); 447 AutofillMetrics::FILLABLE_FORM_CONTAINS_TYPE_HINTS);
436 } 448 }
437 } 449 }
438 } 450 }
439 451
440 bool FormStructure::EncodeUploadRequest( 452 bool FormStructure::EncodeUploadRequest(
441 const ServerFieldTypeSet& available_field_types, 453 const ServerFieldTypeSet& available_field_types,
442 bool form_was_autofilled, 454 bool form_was_autofilled,
443 const std::string& login_form_signature, 455 const std::string& login_form_signature,
444 std::string* encoded_xml) const { 456 std::string* encoded_xml) const {
457 DCHECK(encoded_xml);
445 DCHECK(ShouldBeCrowdsourced()); 458 DCHECK(ShouldBeCrowdsourced());
446 459
447 // Verify that |available_field_types| agrees with the possible field types we 460 // Verify that |available_field_types| agrees with the possible field types we
448 // are uploading. 461 // are uploading.
449 for (const AutofillField* field : *this) { 462 for (const AutofillField* field : *this) {
450 for (const auto& type : field->possible_types()) { 463 for (const auto& type : field->possible_types()) {
451 DCHECK(type == UNKNOWN_TYPE || 464 DCHECK(type == UNKNOWN_TYPE || type == EMPTY_TYPE ||
452 type == EMPTY_TYPE ||
453 available_field_types.count(type)); 465 available_field_types.count(type));
454 } 466 }
455 } 467 }
456 468
457 // Set up the <autofillupload> element and its attributes. 469 // Set up the <autofillupload> element and its attributes.
458 buzz::XmlElement autofill_request_xml( 470 XmlWriter xml_writer;
459 (buzz::QName(kXMLElementAutofillUpload))); 471 xml_writer.StartWriting();
460 autofill_request_xml.SetAttr(buzz::QName(kAttributeClientVersion), 472 xml_writer.StopIndenting();
461 kClientVersion); 473 if (!xml_writer.StartElement(kXMLElementAutofillUpload))
462 autofill_request_xml.SetAttr(buzz::QName(kAttributeFormSignature), 474 return false;
463 FormSignature()); 475 if (!xml_writer.AddAttribute(kAttributeClientVersion, kClientVersion))
464 autofill_request_xml.SetAttr(buzz::QName(kAttributeAutofillUsed), 476 return false;
465 form_was_autofilled ? "true" : "false"); 477 if (!xml_writer.AddAttribute(kAttributeFormSignature, FormSignature()))
466 autofill_request_xml.SetAttr(buzz::QName(kAttributeDataPresent), 478 return false;
467 EncodeFieldTypes(available_field_types).c_str()); 479 if (!xml_writer.AddAttribute(kAttributeAutofillUsed,
480 form_was_autofilled ? "true" : "false"))
481 return false;
482 if (!xml_writer.AddAttribute(kAttributeDataPresent,
483 EncodeFieldTypes(available_field_types)))
484 return false;
468 if (IsAutofillFieldMetadataEnabled()) { 485 if (IsAutofillFieldMetadataEnabled()) {
469 autofill_request_xml.SetAttr(buzz::QName(kAttributeFormActionHostSignature), 486 if (!xml_writer.AddAttribute(kAttributeFormActionHostSignature,
470 Hash64Bit(target_url_.host())); 487 Hash64Bit(target_url_.host())))
471 if(!form_name().empty()) { 488 return false;
472 autofill_request_xml.SetAttr(buzz::QName(kAttributeFormName), 489 if (!form_name().empty()) {
473 base::UTF16ToUTF8(form_name())); 490 if (!xml_writer.AddAttribute(kAttributeFormName,
491 base::UTF16ToUTF8(form_name())))
492 return false;
474 } 493 }
475 } 494 }
476 495
477 if (!login_form_signature.empty()) { 496 if (!login_form_signature.empty()) {
478 autofill_request_xml.SetAttr(buzz::QName(kAttributeLoginFormSignature), 497 if (!xml_writer.AddAttribute(kAttributeLoginFormSignature,
479 login_form_signature); 498 login_form_signature))
499 return false;
480 } 500 }
481 501
482 if (!EncodeFormRequest(FormStructure::UPLOAD, &autofill_request_xml)) 502 if (IsMalformed() || !EncodeFormRequest(FormStructure::UPLOAD, &xml_writer))
483 return false; // Malformed form, skip it. 503 return false; // Malformed form, skip it.
504 if (!xml_writer.EndElement())
505 return false;
484 506
485 // Obtain the XML structure as a string. 507 // Obtain the XML structure as a string.
486 *encoded_xml = kXMLDeclaration; 508 xml_writer.StopWriting();
487 *encoded_xml += autofill_request_xml.Str().c_str(); 509 *encoded_xml = xml_writer.GetWrittenString();
488 510
489 // To enable this logging, run with the flag --vmodule="form_structure=2". 511 // To enable this logging, run with the flag --vmodule="form_structure=2".
490 VLOG(2) << "\n" << *encoded_xml; 512 VLOG(2) << "\n" << *encoded_xml;
491 513
492 return true; 514 return true;
493 } 515 }
494 516
495 bool FormStructure::EncodeFieldAssignments( 517 bool FormStructure::EncodeFieldAssignments(
496 const ServerFieldTypeSet& available_field_types, 518 const ServerFieldTypeSet& available_field_types,
497 std::string* encoded_xml) const { 519 std::string* encoded_xml) const {
520 DCHECK(encoded_xml);
498 DCHECK(ShouldBeCrowdsourced()); 521 DCHECK(ShouldBeCrowdsourced());
499 522
500 // Set up the <fieldassignments> element and its attributes. 523 // Set up the <fieldassignments> element and its attributes.
501 buzz::XmlElement autofill_request_xml( 524 XmlWriter xml_writer;
502 (buzz::QName(kXMLElementFieldAssignments))); 525 xml_writer.StartWriting();
503 autofill_request_xml.SetAttr(buzz::QName(kAttributeFormSignature), 526 xml_writer.StopIndenting();
504 FormSignature()); 527 if (!xml_writer.StartElement(kXMLElementFieldAssignments))
528 return false;
529 if (!xml_writer.AddAttribute(kAttributeFormSignature, FormSignature()))
530 return false;
505 531
506 if (!EncodeFormRequest(FormStructure::FIELD_ASSIGNMENTS, 532 if (IsMalformed() ||
507 &autofill_request_xml)) 533 !EncodeFormRequest(FormStructure::FIELD_ASSIGNMENTS, &xml_writer)) {
508 return false; // Malformed form, skip it. 534 return false; // Malformed form, skip it.
535 }
536 if (!xml_writer.EndElement())
537 return false;
509 538
510 // Obtain the XML structure as a string. 539 // Obtain the XML structure as a string.
511 *encoded_xml = kXMLDeclaration; 540 xml_writer.StopWriting();
512 *encoded_xml += autofill_request_xml.Str().c_str(); 541 *encoded_xml = xml_writer.GetWrittenString();
513 542
514 return true; 543 return true;
515 } 544 }
516 545
517 // static 546 // static
518 bool FormStructure::EncodeQueryRequest( 547 bool FormStructure::EncodeQueryRequest(
519 const std::vector<FormStructure*>& forms, 548 const std::vector<FormStructure*>& forms,
520 std::vector<std::string>* encoded_signatures, 549 std::vector<std::string>* encoded_signatures,
521 std::string* encoded_xml) { 550 std::string* encoded_xml) {
522 DCHECK(encoded_signatures); 551 DCHECK(encoded_signatures);
523 DCHECK(encoded_xml); 552 DCHECK(encoded_xml);
524 encoded_xml->clear();
525 encoded_signatures->clear(); 553 encoded_signatures->clear();
526 encoded_signatures->reserve(forms.size()); 554 encoded_signatures->reserve(forms.size());
527 555
528 // Set up the <autofillquery> element and attributes. 556 // Set up the <autofillquery> element and attributes.
529 buzz::XmlElement autofill_request_xml( 557 XmlWriter xml_writer;
530 (buzz::QName(kXMLElementAutofillQuery))); 558 xml_writer.StartWriting();
531 autofill_request_xml.SetAttr(buzz::QName(kAttributeClientVersion), 559 xml_writer.StopIndenting();
532 kClientVersion); 560 if (!xml_writer.StartElement(kXMLElementAutofillQuery))
561 return false;
562 if (!xml_writer.AddAttribute(kAttributeClientVersion, kClientVersion))
563 return false;
533 564
534 // Some badly formatted web sites repeat forms - detect that and encode only 565 // Some badly formatted web sites repeat forms - detect that and encode only
535 // one form as returned data would be the same for all the repeated forms. 566 // one form as returned data would be the same for all the repeated forms.
536 std::set<std::string> processed_forms; 567 std::set<std::string> processed_forms;
537 for (const auto& it : forms) { 568 for (const auto& form : forms) {
538 std::string signature(it->FormSignature()); 569 std::string signature(form->FormSignature());
539 if (processed_forms.find(signature) != processed_forms.end()) 570 if (processed_forms.find(signature) != processed_forms.end())
540 continue; 571 continue;
541 processed_forms.insert(signature); 572 processed_forms.insert(signature);
542 scoped_ptr<buzz::XmlElement> encompassing_xml_element( 573 if (form->IsMalformed())
543 new buzz::XmlElement(buzz::QName(kXMLElementForm))); 574 continue;
544 encompassing_xml_element->SetAttr(buzz::QName(kAttributeSignature), 575 if (!xml_writer.StartElement(kXMLElementForm))
545 signature); 576 return false;
577 if (!xml_writer.AddAttribute(kAttributeSignature, signature))
578 return false;
546 579
547 if (!it->EncodeFormRequest(FormStructure::QUERY, 580 if (!form->EncodeFormRequest(FormStructure::QUERY, &xml_writer))
548 encompassing_xml_element.get())) { 581 continue;
549 continue; // Malformed form, skip it.
550 }
551 582
552 autofill_request_xml.AddElement(encompassing_xml_element.release()); 583 if (!xml_writer.EndElement())
584 return false;
585
553 encoded_signatures->push_back(signature); 586 encoded_signatures->push_back(signature);
554 } 587 }
588 if (!xml_writer.EndElement())
589 return false;
555 590
556 if (!encoded_signatures->size()) 591 if (!encoded_signatures->size())
557 return false; 592 return false;
558 593
559 // Note: Chrome used to also set 'accepts="e"' (where 'e' is for experiments), 594 // Note: Chrome used to also set 'accepts="e"' (where 'e' is for experiments),
560 // but no longer sets this because support for experiments is deprecated. If 595 // but no longer sets this because support for experiments is deprecated. If
561 // it ever resurfaces, re-add code here to set the attribute accordingly. 596 // it ever resurfaces, re-add code here to set the attribute accordingly.
562 597
563 // Obtain the XML structure as a string. 598 // Obtain the XML structure as a string.
564 *encoded_xml = kXMLDeclaration; 599 xml_writer.StopWriting();
565 *encoded_xml += autofill_request_xml.Str().c_str(); 600 *encoded_xml = xml_writer.GetWrittenString();
566 601
567 return true; 602 return true;
568 } 603 }
569 604
570 // static 605 // static
571 void FormStructure::ParseQueryResponse(const std::string& response_xml, 606 void FormStructure::ParseQueryResponse(std::string response_xml,
572 const std::vector<FormStructure*>& forms, 607 const std::vector<FormStructure*>& forms,
573 rappor::RapporService* rappor_service) { 608 rappor::RapporService* rappor_service) {
574 AutofillMetrics::LogServerQueryMetric( 609 AutofillMetrics::LogServerQueryMetric(
575 AutofillMetrics::QUERY_RESPONSE_RECEIVED); 610 AutofillMetrics::QUERY_RESPONSE_RECEIVED);
576 611
577 // Parse the field types from the server response to the query. 612 // Parse the field types from the server response to the query.
578 std::vector<AutofillServerFieldInfo> field_infos; 613 std::vector<AutofillServerFieldInfo> field_infos;
579 UploadRequired upload_required; 614 UploadRequired upload_required;
580 AutofillQueryXmlParser parse_handler(&field_infos, 615 if (!ParseAutofillQueryXml(response_xml, &field_infos, &upload_required))
581 &upload_required);
582 buzz::XmlParser parser(&parse_handler);
583 parser.Parse(response_xml.c_str(), response_xml.length(), true);
584 if (!parse_handler.succeeded())
585 return; 616 return;
586 617
587 AutofillMetrics::LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_PARSED); 618 AutofillMetrics::LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_PARSED);
588 619
589 bool heuristics_detected_fillable_field = false; 620 bool heuristics_detected_fillable_field = false;
590 bool query_response_overrode_heuristics = false; 621 bool query_response_overrode_heuristics = false;
591 622
592 // Copy the field types into the actual form. 623 // Copy the field types into the actual form.
593 std::vector<AutofillServerFieldInfo>::iterator current_info = 624 std::vector<AutofillServerFieldInfo>::iterator current_info =
594 field_infos.begin(); 625 field_infos.begin();
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 (((static_cast<uint64>(hash_bin[2])) & 0xFF) << 40) | 1051 (((static_cast<uint64>(hash_bin[2])) & 0xFF) << 40) |
1021 (((static_cast<uint64>(hash_bin[3])) & 0xFF) << 32) | 1052 (((static_cast<uint64>(hash_bin[3])) & 0xFF) << 32) |
1022 (((static_cast<uint64>(hash_bin[4])) & 0xFF) << 24) | 1053 (((static_cast<uint64>(hash_bin[4])) & 0xFF) << 24) |
1023 (((static_cast<uint64>(hash_bin[5])) & 0xFF) << 16) | 1054 (((static_cast<uint64>(hash_bin[5])) & 0xFF) << 16) |
1024 (((static_cast<uint64>(hash_bin[6])) & 0xFF) << 8) | 1055 (((static_cast<uint64>(hash_bin[6])) & 0xFF) << 8) |
1025 ((static_cast<uint64>(hash_bin[7])) & 0xFF); 1056 ((static_cast<uint64>(hash_bin[7])) & 0xFF);
1026 1057
1027 return base::Uint64ToString(hash64); 1058 return base::Uint64ToString(hash64);
1028 } 1059 }
1029 1060
1030 bool FormStructure::EncodeFormRequest( 1061 bool FormStructure::IsMalformed() const {
1031 FormStructure::EncodeRequestType request_type,
1032 buzz::XmlElement* encompassing_xml_element) const {
1033 if (!field_count()) // Nothing to add. 1062 if (!field_count()) // Nothing to add.
1034 return false; 1063 return true;
1035 1064
1036 // Some badly formatted web sites repeat fields - limit number of fields to 1065 // Some badly formatted web sites repeat fields - limit number of fields to
1037 // 48, which is far larger than any valid form and XML still fits into 2K. 1066 // 48, which is far larger than any valid form and XML still fits into 2K.
1038 // Do not send requests for forms with more than this many fields, as they are 1067 // Do not send requests for forms with more than this many fields, as they are
1039 // near certainly not valid/auto-fillable. 1068 // near certainly not valid/auto-fillable.
1040 const size_t kMaxFieldsOnTheForm = 48; 1069 const size_t kMaxFieldsOnTheForm = 48;
1041 if (field_count() > kMaxFieldsOnTheForm) 1070 if (field_count() > kMaxFieldsOnTheForm)
1042 return false; 1071 return true;
1072 return false;
1073 }
1043 1074
1075 bool FormStructure::EncodeFormRequest(EncodeRequestType request_type,
1076 XmlWriter* xml_writer) const {
1077 DCHECK(!IsMalformed());
1044 // Add the child nodes for the form fields. 1078 // Add the child nodes for the form fields.
1045 for (size_t index = 0; index < field_count(); ++index) { 1079 for (const AutofillField* field : fields_) {
1046 const AutofillField* field = fields_[index];
1047 switch (request_type) { 1080 switch (request_type) {
1048 case FormStructure::UPLOAD: 1081 case FormStructure::UPLOAD:
1049 EncodeFieldForUpload(*field, encompassing_xml_element); 1082 if (!EncodeFieldForUpload(*field, xml_writer))
1083 return false;
1050 break; 1084 break;
1051 case FormStructure::QUERY: 1085 case FormStructure::QUERY:
1052 if (ShouldSkipField(*field)) 1086 if (ShouldSkipField(*field))
1053 continue; 1087 continue;
1054 EncodeFieldForQuery(*field, encompassing_xml_element); 1088 if (!xml_writer->StartElement(kXMLElementField))
1089 return false;
1090 if (!EncodeFieldForQuery(*field, xml_writer))
1091 return false;
1092 if (!xml_writer->EndElement())
1093 return false;
1055 break; 1094 break;
1056 case FormStructure::FIELD_ASSIGNMENTS: 1095 case FormStructure::FIELD_ASSIGNMENTS:
1057 EncodeFieldForFieldAssignments(*field, encompassing_xml_element); 1096 if (!EncodeFieldForFieldAssignments(*field, xml_writer))
1097 return false;
1058 break; 1098 break;
1059 } 1099 }
1060 } 1100 }
1061 return true; 1101 return true;
1062 } 1102 }
1063 1103
1064 void FormStructure::ParseFieldTypesFromAutocompleteAttributes() { 1104 void FormStructure::ParseFieldTypesFromAutocompleteAttributes() {
1065 const std::string kDefaultSection = "-default"; 1105 const std::string kDefaultSection = "-default";
1066 1106
1067 has_author_specified_types_ = false; 1107 has_author_specified_types_ = false;
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 for (AutofillField* field : fields_) { 1350 for (AutofillField* field : fields_) {
1311 FieldTypeGroup field_type_group = field->Type().group(); 1351 FieldTypeGroup field_type_group = field->Type().group();
1312 if (field_type_group == CREDIT_CARD) 1352 if (field_type_group == CREDIT_CARD)
1313 field->set_section(field->section() + "-cc"); 1353 field->set_section(field->section() + "-cc");
1314 else 1354 else
1315 field->set_section(field->section() + "-default"); 1355 field->set_section(field->section() + "-default");
1316 } 1356 }
1317 } 1357 }
1318 1358
1319 } // namespace autofill 1359 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/core/browser/form_structure.h ('k') | components/autofill/core/browser/form_structure_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698