blob: 5ac92fd581c229caac832470e54a0fc8e78889ac [file] [log] [blame]
[email protected]663bd9e2011-03-21 01:07:011// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]ec64212b2010-03-18 01:02:432// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]e4b2fa32013-03-09 22:56:565#include "components/autofill/browser/autofill_xml_parser.h"
[email protected]ec64212b2010-03-18 01:02:436
[email protected]8f608c52011-03-30 16:16:317#include <stdlib.h>
8#include <string.h>
9
10#include "base/logging.h"
[email protected]e4b2fa32013-03-09 22:56:5611#include "components/autofill/browser/autofill_server_field_info.h"
[email protected]0116cf52011-11-01 02:44:3212#include "third_party/libjingle/source/talk/xmllite/qname.h"
[email protected]ec64212b2010-03-18 01:02:4313
[email protected]e217c5632013-04-12 19:11:4814namespace autofill {
15
[email protected]663bd9e2011-03-21 01:07:0116AutofillXmlParser::AutofillXmlParser()
[email protected]ec64212b2010-03-18 01:02:4317 : succeeded_(true) {
18}
19
[email protected]7c5935d2013-01-24 19:11:4320AutofillXmlParser::~AutofillXmlParser() {}
21
[email protected]663bd9e2011-03-21 01:07:0122void AutofillXmlParser::CharacterData(
[email protected]ec64212b2010-03-18 01:02:4323 buzz::XmlParseContext* context, const char* text, int len) {
24}
25
[email protected]663bd9e2011-03-21 01:07:0126void AutofillXmlParser::EndElement(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:4327 const char* name) {
28}
29
[email protected]663bd9e2011-03-21 01:07:0130void AutofillXmlParser::Error(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:4331 XML_Error error_code) {
32 succeeded_ = false;
33}
34
[email protected]663bd9e2011-03-21 01:07:0135AutofillQueryXmlParser::AutofillQueryXmlParser(
[email protected]732acb02013-01-22 17:04:4536 std::vector<AutofillServerFieldInfo>* field_infos,
[email protected]5f372f82011-01-31 23:20:5037 UploadRequired* upload_required,
38 std::string* experiment_id)
[email protected]732acb02013-01-22 17:04:4539 : field_infos_(field_infos),
[email protected]5f372f82011-01-31 23:20:5040 upload_required_(upload_required),
[email protected]e899b962013-01-18 20:52:0841 current_page_number_(-1),
42 total_pages_(-1),
[email protected]5f372f82011-01-31 23:20:5043 experiment_id_(experiment_id) {
[email protected]ec64212b2010-03-18 01:02:4344 DCHECK(upload_required_);
[email protected]5f372f82011-01-31 23:20:5045 DCHECK(experiment_id_);
[email protected]ec64212b2010-03-18 01:02:4346}
47
[email protected]7c5935d2013-01-24 19:11:4348AutofillQueryXmlParser::~AutofillQueryXmlParser() {}
49
[email protected]663bd9e2011-03-21 01:07:0150void AutofillQueryXmlParser::StartElement(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:4351 const char* name,
52 const char** attrs) {
53 buzz::QName qname = context->ResolveQName(name, false);
[email protected]5f372f82011-01-31 23:20:5054 const std::string& element = qname.LocalPart();
[email protected]ec64212b2010-03-18 01:02:4355 if (element.compare("autofillqueryresponse") == 0) {
[email protected]5f372f82011-01-31 23:20:5056 // We check for the upload required attribute below, but if it's not
57 // present, we use the default upload rates. Likewise, by default we assume
58 // an empty experiment id.
[email protected]ec64212b2010-03-18 01:02:4359 *upload_required_ = USE_UPLOAD_RATES;
[email protected]5f372f82011-01-31 23:20:5060 *experiment_id_ = std::string();
61
62 // |attrs| is a NULL-terminated list of (attribute, value) pairs.
63 while (*attrs) {
[email protected]732acb02013-01-22 17:04:4564 buzz::QName attribute_qname = context->ResolveQName(*attrs, true);
65 ++attrs;
[email protected]5f372f82011-01-31 23:20:5066 const std::string& attribute_name = attribute_qname.LocalPart();
[email protected]ec64212b2010-03-18 01:02:4367 if (attribute_name.compare("uploadrequired") == 0) {
[email protected]732acb02013-01-22 17:04:4568 if (strcmp(*attrs, "true") == 0)
[email protected]ec64212b2010-03-18 01:02:4369 *upload_required_ = UPLOAD_REQUIRED;
[email protected]732acb02013-01-22 17:04:4570 else if (strcmp(*attrs, "false") == 0)
[email protected]ec64212b2010-03-18 01:02:4371 *upload_required_ = UPLOAD_NOT_REQUIRED;
[email protected]5f372f82011-01-31 23:20:5072 } else if (attribute_name.compare("experimentid") == 0) {
[email protected]732acb02013-01-22 17:04:4573 *experiment_id_ = *attrs;
[email protected]ec64212b2010-03-18 01:02:4374 }
[email protected]732acb02013-01-22 17:04:4575 ++attrs;
[email protected]ec64212b2010-03-18 01:02:4376 }
77 } else if (element.compare("field") == 0) {
[email protected]732acb02013-01-22 17:04:4578 if (!*attrs) {
[email protected]ec64212b2010-03-18 01:02:4379 // Missing the "autofilltype" attribute, abort.
80 context->RaiseError(XML_ERROR_ABORTED);
81 return;
82 }
83
84 // Determine the field type from the attribute value. There should be one
85 // attribute (autofilltype) with an integer value.
[email protected]732acb02013-01-22 17:04:4586 AutofillServerFieldInfo field_info;
87 field_info.field_type = UNKNOWN_TYPE;
[email protected]ec64212b2010-03-18 01:02:4388
[email protected]732acb02013-01-22 17:04:4589 // |attrs| is a NULL-terminated list of (attribute, value) pairs.
90 while (*attrs) {
91 buzz::QName attribute_qname = context->ResolveQName(*attrs, true);
92 ++attrs;
93 const std::string& attribute_name = attribute_qname.LocalPart();
94 if (attribute_name.compare("autofilltype") == 0) {
95 int value = GetIntValue(context, *attrs);
96 if (value >= 0 && value < MAX_VALID_FIELD_TYPE)
97 field_info.field_type = static_cast<AutofillFieldType>(value);
98 else
99 field_info.field_type = NO_SERVER_DATA;
100 } else if (field_info.field_type == FIELD_WITH_DEFAULT_VALUE &&
101 attribute_name.compare("defaultvalue") == 0) {
102 field_info.default_value = *attrs;
[email protected]ec64212b2010-03-18 01:02:43103 }
[email protected]732acb02013-01-22 17:04:45104 ++attrs;
[email protected]ec64212b2010-03-18 01:02:43105 }
106
[email protected]732acb02013-01-22 17:04:45107 // Record this field type, default value pair.
108 field_infos_->push_back(field_info);
[email protected]e899b962013-01-18 20:52:08109 } else if (element.compare("autofill_flow") == 0) {
110 // |attrs| is a NULL-terminated list of (attribute, value) pairs.
111 while (*attrs) {
112 buzz::QName attribute_qname = context->ResolveQName(*attrs, true);
113 ++attrs;
114 const std::string& attribute_name = attribute_qname.LocalPart();
115 if (attribute_name.compare("page_no") == 0)
116 current_page_number_ = GetIntValue(context, *attrs);
117 else if (attribute_name.compare("total_pages") == 0)
118 total_pages_ = GetIntValue(context, *attrs);
119 ++attrs;
120 }
[email protected]7c5935d2013-01-24 19:11:43121 } else if (element.compare("page_advance_button") == 0) {
122 // |attrs| is a NULL-terminated list of (attribute, value) pairs.
123 // If both id and css_selector are set, the first one to appear will take
124 // precedence.
125 while (*attrs) {
126 buzz::QName attribute_qname = context->ResolveQName(*attrs, true);
127 ++attrs;
128 const std::string& attribute_name = attribute_qname.LocalPart();
129 buzz::QName value_qname = context->ResolveQName(*attrs, true);
130 ++attrs;
131 const std::string& attribute_value = value_qname.LocalPart();
132 if (attribute_name.compare("id") == 0 && !attribute_value.empty()) {
133 proceed_element_descriptor_.reset(new autofill::WebElementDescriptor());
134 proceed_element_descriptor_->retrieval_method =
135 autofill::WebElementDescriptor::ID;
136 proceed_element_descriptor_->descriptor = attribute_value;
137 break;
138 } else if (attribute_name.compare("css_selector") == 0 &&
139 !attribute_value.empty()) {
140 proceed_element_descriptor_.reset(new autofill::WebElementDescriptor());
141 proceed_element_descriptor_->retrieval_method =
142 autofill::WebElementDescriptor::CSS_SELECTOR;
143 proceed_element_descriptor_->descriptor = attribute_value;
144 break;
145 }
146 }
[email protected]ec64212b2010-03-18 01:02:43147 }
148}
149
[email protected]663bd9e2011-03-21 01:07:01150int AutofillQueryXmlParser::GetIntValue(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:43151 const char* attribute) {
152 char* attr_end = NULL;
153 int value = strtol(attribute, &attr_end, 10);
154 if (attr_end != NULL && attr_end == attribute) {
155 context->RaiseError(XML_ERROR_SYNTAX);
156 return 0;
157 }
158 return value;
159}
160
[email protected]663bd9e2011-03-21 01:07:01161AutofillUploadXmlParser::AutofillUploadXmlParser(double* positive_upload_rate,
[email protected]ec64212b2010-03-18 01:02:43162 double* negative_upload_rate)
[email protected]8cd7fd02010-07-22 18:21:02163 : succeeded_(false),
164 positive_upload_rate_(positive_upload_rate),
[email protected]ec64212b2010-03-18 01:02:43165 negative_upload_rate_(negative_upload_rate) {
166 DCHECK(positive_upload_rate_);
167 DCHECK(negative_upload_rate_);
168}
169
[email protected]663bd9e2011-03-21 01:07:01170void AutofillUploadXmlParser::StartElement(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:43171 const char* name,
172 const char** attrs) {
173 buzz::QName qname = context->ResolveQName(name, false);
174 const std::string &element = qname.LocalPart();
175 if (element.compare("autofilluploadresponse") == 0) {
176 // Loop over all attributes to get the upload rates.
177 while (*attrs) {
178 buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
179 const std::string &attribute_name = attribute_qname.LocalPart();
180 if (attribute_name.compare("positiveuploadrate") == 0) {
181 *positive_upload_rate_ = GetDoubleValue(context, attrs[1]);
182 } else if (attribute_name.compare("negativeuploadrate") == 0) {
183 *negative_upload_rate_ = GetDoubleValue(context, attrs[1]);
184 }
185 attrs += 2; // We peeked at attrs[0] and attrs[1], skip past both.
186 }
187 }
188}
189
[email protected]663bd9e2011-03-21 01:07:01190double AutofillUploadXmlParser::GetDoubleValue(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:43191 const char* attribute) {
192 char* attr_end = NULL;
193 double value = strtod(attribute, &attr_end);
194 if (attr_end != NULL && attr_end == attribute) {
195 context->RaiseError(XML_ERROR_SYNTAX);
196 return 0.0;
197 }
198 return value;
199}
[email protected]e217c5632013-04-12 19:11:48200
201} // namespace autofill