• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "third_party/libjingle/overrides/talk/xmllite/qname.h"
12 
AutofillXmlParser()13 AutofillXmlParser::AutofillXmlParser()
14     : succeeded_(true) {
15 }
16 
CharacterData(buzz::XmlParseContext * context,const char * text,int len)17 void AutofillXmlParser::CharacterData(
18     buzz::XmlParseContext* context, const char* text, int len) {
19 }
20 
EndElement(buzz::XmlParseContext * context,const char * name)21 void AutofillXmlParser::EndElement(buzz::XmlParseContext* context,
22                                    const char* name) {
23 }
24 
Error(buzz::XmlParseContext * context,XML_Error error_code)25 void AutofillXmlParser::Error(buzz::XmlParseContext* context,
26                               XML_Error error_code) {
27   succeeded_ = false;
28 }
29 
AutofillQueryXmlParser(std::vector<AutofillFieldType> * field_types,UploadRequired * upload_required,std::string * experiment_id)30 AutofillQueryXmlParser::AutofillQueryXmlParser(
31     std::vector<AutofillFieldType>* field_types,
32     UploadRequired* upload_required,
33     std::string* experiment_id)
34     : field_types_(field_types),
35       upload_required_(upload_required),
36       experiment_id_(experiment_id) {
37   DCHECK(upload_required_);
38   DCHECK(experiment_id_);
39 }
40 
StartElement(buzz::XmlParseContext * context,const char * name,const char ** attrs)41 void AutofillQueryXmlParser::StartElement(buzz::XmlParseContext* context,
42                                           const char* name,
43                                           const char** attrs) {
44   buzz::QName qname = context->ResolveQName(name, false);
45   const std::string& element = qname.LocalPart();
46   if (element.compare("autofillqueryresponse") == 0) {
47     // We check for the upload required attribute below, but if it's not
48     // present, we use the default upload rates. Likewise, by default we assume
49     // an empty experiment id.
50     *upload_required_ = USE_UPLOAD_RATES;
51     *experiment_id_ = std::string();
52 
53     // |attrs| is a NULL-terminated list of (attribute, value) pairs.
54     while (*attrs) {
55       buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
56       const std::string& attribute_name = attribute_qname.LocalPart();
57       if (attribute_name.compare("uploadrequired") == 0) {
58         if (strcmp(attrs[1], "true") == 0)
59           *upload_required_ = UPLOAD_REQUIRED;
60         else if (strcmp(attrs[1], "false") == 0)
61           *upload_required_ = UPLOAD_NOT_REQUIRED;
62       } else if (attribute_name.compare("experimentid") == 0) {
63         *experiment_id_ = attrs[1];
64       }
65 
66       // Advance to the next (attribute, value) pair.
67       attrs += 2;
68     }
69   } else if (element.compare("field") == 0) {
70     if (!attrs[0]) {
71       // Missing the "autofilltype" attribute, abort.
72       context->RaiseError(XML_ERROR_ABORTED);
73       return;
74     }
75 
76     // Determine the field type from the attribute value.  There should be one
77     // attribute (autofilltype) with an integer value.
78     AutofillFieldType field_type = UNKNOWN_TYPE;
79     buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
80     const std::string& attribute_name = attribute_qname.LocalPart();
81 
82     if (attribute_name.compare("autofilltype") == 0) {
83       int value = GetIntValue(context, attrs[1]);
84       field_type = static_cast<AutofillFieldType>(value);
85       if (field_type < 0 || field_type > MAX_VALID_FIELD_TYPE) {
86         field_type = NO_SERVER_DATA;
87       }
88     }
89 
90     // Record this field type.
91     field_types_->push_back(field_type);
92   }
93 }
94 
GetIntValue(buzz::XmlParseContext * context,const char * attribute)95 int AutofillQueryXmlParser::GetIntValue(buzz::XmlParseContext* context,
96                                         const char* attribute) {
97   char* attr_end = NULL;
98   int value = strtol(attribute, &attr_end, 10);
99   if (attr_end != NULL && attr_end == attribute) {
100     context->RaiseError(XML_ERROR_SYNTAX);
101     return 0;
102   }
103   return value;
104 }
105 
AutofillUploadXmlParser(double * positive_upload_rate,double * negative_upload_rate)106 AutofillUploadXmlParser::AutofillUploadXmlParser(double* positive_upload_rate,
107                                                  double* negative_upload_rate)
108     : succeeded_(false),
109       positive_upload_rate_(positive_upload_rate),
110       negative_upload_rate_(negative_upload_rate) {
111   DCHECK(positive_upload_rate_);
112   DCHECK(negative_upload_rate_);
113 }
114 
StartElement(buzz::XmlParseContext * context,const char * name,const char ** attrs)115 void AutofillUploadXmlParser::StartElement(buzz::XmlParseContext* context,
116                                            const char* name,
117                                            const char** attrs) {
118   buzz::QName qname = context->ResolveQName(name, false);
119   const std::string &element = qname.LocalPart();
120   if (element.compare("autofilluploadresponse") == 0) {
121     // Loop over all attributes to get the upload rates.
122     while (*attrs) {
123       buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
124       const std::string &attribute_name = attribute_qname.LocalPart();
125       if (attribute_name.compare("positiveuploadrate") == 0) {
126         *positive_upload_rate_ = GetDoubleValue(context, attrs[1]);
127       } else if (attribute_name.compare("negativeuploadrate") == 0) {
128         *negative_upload_rate_ = GetDoubleValue(context, attrs[1]);
129       }
130       attrs += 2;  // We peeked at attrs[0] and attrs[1], skip past both.
131     }
132   }
133 }
134 
GetDoubleValue(buzz::XmlParseContext * context,const char * attribute)135 double AutofillUploadXmlParser::GetDoubleValue(buzz::XmlParseContext* context,
136                                                const char* attribute) {
137   char* attr_end = NULL;
138   double value = strtod(attribute, &attr_end);
139   if (attr_end != NULL && attr_end == attribute) {
140     context->RaiseError(XML_ERROR_SYNTAX);
141     return 0.0;
142   }
143   return value;
144 }
145