| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/autofill/autofill_xml_parser.h" | |
| 6 | |
| 7 #include <stdlib.h> | |
| 8 #include <string.h> | |
| 9 | |
| 10 #include "base/logging.h" | |
| 11 #include "chrome/browser/autofill/autofill_server_field_info.h" | |
| 12 #include "third_party/libjingle/source/talk/xmllite/qname.h" | |
| 13 | |
| 14 AutofillXmlParser::AutofillXmlParser() | |
| 15 : succeeded_(true) { | |
| 16 } | |
| 17 | |
| 18 AutofillXmlParser::~AutofillXmlParser() {} | |
| 19 | |
| 20 void AutofillXmlParser::CharacterData( | |
| 21 buzz::XmlParseContext* context, const char* text, int len) { | |
| 22 } | |
| 23 | |
| 24 void AutofillXmlParser::EndElement(buzz::XmlParseContext* context, | |
| 25 const char* name) { | |
| 26 } | |
| 27 | |
| 28 void AutofillXmlParser::Error(buzz::XmlParseContext* context, | |
| 29 XML_Error error_code) { | |
| 30 succeeded_ = false; | |
| 31 } | |
| 32 | |
| 33 AutofillQueryXmlParser::AutofillQueryXmlParser( | |
| 34 std::vector<AutofillServerFieldInfo>* field_infos, | |
| 35 UploadRequired* upload_required, | |
| 36 std::string* experiment_id) | |
| 37 : field_infos_(field_infos), | |
| 38 upload_required_(upload_required), | |
| 39 current_page_number_(-1), | |
| 40 total_pages_(-1), | |
| 41 experiment_id_(experiment_id) { | |
| 42 DCHECK(upload_required_); | |
| 43 DCHECK(experiment_id_); | |
| 44 } | |
| 45 | |
| 46 AutofillQueryXmlParser::~AutofillQueryXmlParser() {} | |
| 47 | |
| 48 void AutofillQueryXmlParser::StartElement(buzz::XmlParseContext* context, | |
| 49 const char* name, | |
| 50 const char** attrs) { | |
| 51 buzz::QName qname = context->ResolveQName(name, false); | |
| 52 const std::string& element = qname.LocalPart(); | |
| 53 if (element.compare("autofillqueryresponse") == 0) { | |
| 54 // We check for the upload required attribute below, but if it's not | |
| 55 // present, we use the default upload rates. Likewise, by default we assume | |
| 56 // an empty experiment id. | |
| 57 *upload_required_ = USE_UPLOAD_RATES; | |
| 58 *experiment_id_ = std::string(); | |
| 59 | |
| 60 // |attrs| is a NULL-terminated list of (attribute, value) pairs. | |
| 61 while (*attrs) { | |
| 62 buzz::QName attribute_qname = context->ResolveQName(*attrs, true); | |
| 63 ++attrs; | |
| 64 const std::string& attribute_name = attribute_qname.LocalPart(); | |
| 65 if (attribute_name.compare("uploadrequired") == 0) { | |
| 66 if (strcmp(*attrs, "true") == 0) | |
| 67 *upload_required_ = UPLOAD_REQUIRED; | |
| 68 else if (strcmp(*attrs, "false") == 0) | |
| 69 *upload_required_ = UPLOAD_NOT_REQUIRED; | |
| 70 } else if (attribute_name.compare("experimentid") == 0) { | |
| 71 *experiment_id_ = *attrs; | |
| 72 } | |
| 73 ++attrs; | |
| 74 } | |
| 75 } else if (element.compare("field") == 0) { | |
| 76 if (!*attrs) { | |
| 77 // Missing the "autofilltype" attribute, abort. | |
| 78 context->RaiseError(XML_ERROR_ABORTED); | |
| 79 return; | |
| 80 } | |
| 81 | |
| 82 // Determine the field type from the attribute value. There should be one | |
| 83 // attribute (autofilltype) with an integer value. | |
| 84 AutofillServerFieldInfo field_info; | |
| 85 field_info.field_type = UNKNOWN_TYPE; | |
| 86 | |
| 87 // |attrs| is a NULL-terminated list of (attribute, value) pairs. | |
| 88 while (*attrs) { | |
| 89 buzz::QName attribute_qname = context->ResolveQName(*attrs, true); | |
| 90 ++attrs; | |
| 91 const std::string& attribute_name = attribute_qname.LocalPart(); | |
| 92 if (attribute_name.compare("autofilltype") == 0) { | |
| 93 int value = GetIntValue(context, *attrs); | |
| 94 if (value >= 0 && value < MAX_VALID_FIELD_TYPE) | |
| 95 field_info.field_type = static_cast<AutofillFieldType>(value); | |
| 96 else | |
| 97 field_info.field_type = NO_SERVER_DATA; | |
| 98 } else if (field_info.field_type == FIELD_WITH_DEFAULT_VALUE && | |
| 99 attribute_name.compare("defaultvalue") == 0) { | |
| 100 field_info.default_value = *attrs; | |
| 101 } | |
| 102 ++attrs; | |
| 103 } | |
| 104 | |
| 105 // Record this field type, default value pair. | |
| 106 field_infos_->push_back(field_info); | |
| 107 } else if (element.compare("autofill_flow") == 0) { | |
| 108 // |attrs| is a NULL-terminated list of (attribute, value) pairs. | |
| 109 while (*attrs) { | |
| 110 buzz::QName attribute_qname = context->ResolveQName(*attrs, true); | |
| 111 ++attrs; | |
| 112 const std::string& attribute_name = attribute_qname.LocalPart(); | |
| 113 if (attribute_name.compare("page_no") == 0) | |
| 114 current_page_number_ = GetIntValue(context, *attrs); | |
| 115 else if (attribute_name.compare("total_pages") == 0) | |
| 116 total_pages_ = GetIntValue(context, *attrs); | |
| 117 ++attrs; | |
| 118 } | |
| 119 } else if (element.compare("page_advance_button") == 0) { | |
| 120 // |attrs| is a NULL-terminated list of (attribute, value) pairs. | |
| 121 // If both id and css_selector are set, the first one to appear will take | |
| 122 // precedence. | |
| 123 while (*attrs) { | |
| 124 buzz::QName attribute_qname = context->ResolveQName(*attrs, true); | |
| 125 ++attrs; | |
| 126 const std::string& attribute_name = attribute_qname.LocalPart(); | |
| 127 buzz::QName value_qname = context->ResolveQName(*attrs, true); | |
| 128 ++attrs; | |
| 129 const std::string& attribute_value = value_qname.LocalPart(); | |
| 130 if (attribute_name.compare("id") == 0 && !attribute_value.empty()) { | |
| 131 proceed_element_descriptor_.reset(new autofill::WebElementDescriptor()); | |
| 132 proceed_element_descriptor_->retrieval_method = | |
| 133 autofill::WebElementDescriptor::ID; | |
| 134 proceed_element_descriptor_->descriptor = attribute_value; | |
| 135 break; | |
| 136 } else if (attribute_name.compare("css_selector") == 0 && | |
| 137 !attribute_value.empty()) { | |
| 138 proceed_element_descriptor_.reset(new autofill::WebElementDescriptor()); | |
| 139 proceed_element_descriptor_->retrieval_method = | |
| 140 autofill::WebElementDescriptor::CSS_SELECTOR; | |
| 141 proceed_element_descriptor_->descriptor = attribute_value; | |
| 142 break; | |
| 143 } | |
| 144 } | |
| 145 } | |
| 146 } | |
| 147 | |
| 148 int AutofillQueryXmlParser::GetIntValue(buzz::XmlParseContext* context, | |
| 149 const char* attribute) { | |
| 150 char* attr_end = NULL; | |
| 151 int value = strtol(attribute, &attr_end, 10); | |
| 152 if (attr_end != NULL && attr_end == attribute) { | |
| 153 context->RaiseError(XML_ERROR_SYNTAX); | |
| 154 return 0; | |
| 155 } | |
| 156 return value; | |
| 157 } | |
| 158 | |
| 159 AutofillUploadXmlParser::AutofillUploadXmlParser(double* positive_upload_rate, | |
| 160 double* negative_upload_rate) | |
| 161 : succeeded_(false), | |
| 162 positive_upload_rate_(positive_upload_rate), | |
| 163 negative_upload_rate_(negative_upload_rate) { | |
| 164 DCHECK(positive_upload_rate_); | |
| 165 DCHECK(negative_upload_rate_); | |
| 166 } | |
| 167 | |
| 168 void AutofillUploadXmlParser::StartElement(buzz::XmlParseContext* context, | |
| 169 const char* name, | |
| 170 const char** attrs) { | |
| 171 buzz::QName qname = context->ResolveQName(name, false); | |
| 172 const std::string &element = qname.LocalPart(); | |
| 173 if (element.compare("autofilluploadresponse") == 0) { | |
| 174 // Loop over all attributes to get the upload rates. | |
| 175 while (*attrs) { | |
| 176 buzz::QName attribute_qname = context->ResolveQName(attrs[0], true); | |
| 177 const std::string &attribute_name = attribute_qname.LocalPart(); | |
| 178 if (attribute_name.compare("positiveuploadrate") == 0) { | |
| 179 *positive_upload_rate_ = GetDoubleValue(context, attrs[1]); | |
| 180 } else if (attribute_name.compare("negativeuploadrate") == 0) { | |
| 181 *negative_upload_rate_ = GetDoubleValue(context, attrs[1]); | |
| 182 } | |
| 183 attrs += 2; // We peeked at attrs[0] and attrs[1], skip past both. | |
| 184 } | |
| 185 } | |
| 186 } | |
| 187 | |
| 188 double AutofillUploadXmlParser::GetDoubleValue(buzz::XmlParseContext* context, | |
| 189 const char* attribute) { | |
| 190 char* attr_end = NULL; | |
| 191 double value = strtod(attribute, &attr_end); | |
| 192 if (attr_end != NULL && attr_end == attribute) { | |
| 193 context->RaiseError(XML_ERROR_SYNTAX); | |
| 194 return 0.0; | |
| 195 } | |
| 196 return value; | |
| 197 } | |
| OLD | NEW |