form_structure.cc revision 4a5e2dc747d50c653511c68ccb2cfbfb740bd5a7
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autofill/form_structure.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/sha1.h" 103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autofill/autofill_xml_parser.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autofill/field_types.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autofill/form_field.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/libjingle/source/talk/xmllite/xmlelement.h" 167d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#ifdef ANDROID 177d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#include <WebCoreSupport/autofill/FormFieldAndroid.h> 187d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#else 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/form_field.h" 207d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#endif 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing webkit_glue::FormData; 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* kFormMethodPost = "post"; 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// XML attribute names. 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const kAttributeClientVersion = "clientversion"; 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const kAttributeAutoFillUsed = "autofillused"; 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const kAttributeSignature = "signature"; 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const kAttributeFormSignature = "formsignature"; 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const kAttributeDataPresent = "datapresent"; 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const kXMLElementForm = "form"; 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const kXMLElementField = "field"; 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const kAttributeAutoFillType = "autofilltype"; 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The list of form control types we handle. 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const kControlTypeSelect = "select-one"; 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const kControlTypeText = "text"; 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The number of fillable fields necessary for a form to be fillable. 447d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#ifdef ANDROID 457d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch// Try and autofill more forms on Android, as filling out forms is 467d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch// more frustrating on a mobile device. 477d214dfa174224b459660971e5b5cce2e06be02aBen Murdochconst size_t kRequiredFillableFields = 2; 487d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#else 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst size_t kRequiredFillableFields = 3; 507d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#endif 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic std::string Hash64Bit(const std::string& str) { 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string hash_bin = base::SHA1HashString(str); 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(20U, hash_bin.length()); 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint64 hash64 = (((static_cast<uint64>(hash_bin[0])) & 0xFF) << 56) | 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (((static_cast<uint64>(hash_bin[1])) & 0xFF) << 48) | 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (((static_cast<uint64>(hash_bin[2])) & 0xFF) << 40) | 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (((static_cast<uint64>(hash_bin[3])) & 0xFF) << 32) | 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (((static_cast<uint64>(hash_bin[4])) & 0xFF) << 24) | 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (((static_cast<uint64>(hash_bin[5])) & 0xFF) << 16) | 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (((static_cast<uint64>(hash_bin[6])) & 0xFF) << 8) | 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ((static_cast<uint64>(hash_bin[7])) & 0xFF); 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return base::Uint64ToString(hash64); 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFormStructure::FormStructure(const FormData& form) 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : form_name_(form.name), 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch source_url_(form.origin), 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch target_url_(form.action), 743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick has_credit_card_field_(false), 753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick has_autofillable_field_(false), 763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick has_password_fields_(false), 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch autofill_count_(0) { 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Copy the form fields. 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<webkit_glue::FormField>::const_iterator field; 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (field = form.fields.begin(); 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch field != form.fields.end(); field++) { 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We currently only handle text and select fields; however, we need to 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // store all fields in order to match the fields stored in the FormManager. 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We don't append other field types to the form signature though in order 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to match the form signature of the AutoFill servers. 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (LowerCaseEqualsASCII(field->form_control_type(), kControlTypeText) || 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LowerCaseEqualsASCII(field->form_control_type(), kControlTypeSelect)) { 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add all supported form fields (including with empty names) to 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // signature. This is a requirement for AutoFill servers. 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form_signature_field_names_.append("&"); 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form_signature_field_names_.append(UTF16ToUTF8(field->name())); 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Generate a unique name for this field by appending a counter to the name. 953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick string16 unique_name = field->name() + 963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::IntToString16(fields_.size() + 1); 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch fields_.push_back(new AutoFillField(*field, unique_name)); 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Terminate the vector with a NULL item. 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch fields_.push_back(NULL); 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetHeuristicAutoFillTypes(); 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string method = UTF16ToUTF8(form.method); 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (StringToLowerASCII(method) == kFormMethodPost) { 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch method_ = POST; 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Either the method is 'get', or we don't know. In this case we default 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to GET. 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch method_ = GET; 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 114731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickFormStructure::~FormStructure() {} 115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool FormStructure::EncodeUploadRequest(bool auto_fill_used, 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string* encoded_xml) const { 118513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(encoded_xml); 119513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch encoded_xml->clear(); 1204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch bool auto_fillable = IsAutoFillable(false); 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(auto_fillable); // Caller should've checked for search pages. 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!auto_fillable) 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buzz::XmlElement autofil_request_xml(buzz::QName("autofillupload")); 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Attributes for the <autofillupload> element. 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(jhawkins): Work with toolbar devs to make a spec for autofill clients. 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // For now these values are hacked from the toolbar code. 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch autofil_request_xml.SetAttr(buzz::QName(kAttributeClientVersion), 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "6.1.1715.1442/en (GGLL)"); 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch autofil_request_xml.SetAttr(buzz::QName(kAttributeFormSignature), 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FormSignature()); 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch autofil_request_xml.SetAttr(buzz::QName(kAttributeAutoFillUsed), 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch auto_fill_used ? "true" : "false"); 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(jhawkins): Hook this up to the personal data manager. 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // personaldata_manager_->GetDataPresent(); 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch autofil_request_xml.SetAttr(buzz::QName(kAttributeDataPresent), ""); 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 144513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!EncodeFormRequest(FormStructure::UPLOAD, &autofil_request_xml)) 145513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; // Malformed form, skip it. 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Obtain the XML structure as a string. 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *encoded_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *encoded_xml += autofil_request_xml.Str().c_str(); 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool FormStructure::EncodeQueryRequest(const ScopedVector<FormStructure>& forms, 156513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::vector<std::string>* encoded_signatures, 157513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string* encoded_xml) { 158513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(encoded_signatures); 159513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(encoded_xml); 160513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch encoded_xml->clear(); 161513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch encoded_signatures->clear(); 162513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch encoded_signatures->reserve(forms.size()); 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buzz::XmlElement autofil_request_xml(buzz::QName("autofillquery")); 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Attributes for the <autofillquery> element. 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(jhawkins): Work with toolbar devs to make a spec for autofill clients. 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // For now these values are hacked from the toolbar code. 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch autofil_request_xml.SetAttr(buzz::QName(kAttributeClientVersion), 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "6.1.1715.1442/en (GGLL)"); 170513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Some badly formatted web sites repeat forms - detect that and encode only 171513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // one form as returned data would be the same for all the repeated forms. 172513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::set<std::string> processed_forms; 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (ScopedVector<FormStructure>::const_iterator it = forms.begin(); 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it != forms.end(); 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++it) { 176513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string signature((*it)->FormSignature()); 177513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (processed_forms.find(signature) != processed_forms.end()) 178513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch continue; 179513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch processed_forms.insert(signature); 180513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<buzz::XmlElement> encompassing_xml_element( 181513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new buzz::XmlElement(buzz::QName("form"))); 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch encompassing_xml_element->SetAttr(buzz::QName(kAttributeSignature), 183513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch signature); 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 185513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!(*it)->EncodeFormRequest(FormStructure::QUERY, 186513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch encompassing_xml_element.get())) 187513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch continue; // Malformed form, skip it. 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 189513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch autofil_request_xml.AddElement(encompassing_xml_element.release()); 190513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch encoded_signatures->push_back(signature); 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 193513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!encoded_signatures->size()) 194513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 195513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Obtain the XML structure as a string. 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *encoded_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *encoded_xml += autofil_request_xml.Str().c_str(); 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FormStructure::ParseQueryResponse(const std::string& response_xml, 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<FormStructure*>& forms, 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UploadRequired* upload_required) { 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Parse the field types from the server response to the query. 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<AutoFillFieldType> field_types; 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AutoFillQueryXmlParser parse_handler(&field_types, upload_required); 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buzz::XmlParser parser(&parse_handler); 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch parser.Parse(response_xml.c_str(), response_xml.length(), true); 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!parse_handler.succeeded()) 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Copy the field types into the actual form. 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<AutoFillFieldType>::iterator current_type = field_types.begin(); 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (std::vector<FormStructure*>::const_iterator iter = forms.begin(); 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch iter != forms.end(); ++iter) { 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FormStructure* form = *iter; 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->has_credit_card_field_ = false; 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->has_autofillable_field_ = false; 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (std::vector<AutoFillField*>::iterator field = form->fields_.begin(); 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch field != form->fields_.end(); ++field) { 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The field list is terminated by a NULL AutoFillField. 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!*field) 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // In some cases *successful* response does not return all the fields. 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Quit the update of the types then. 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (current_type == field_types.end()) 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*field)->set_server_type(*current_type); 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AutoFillType autofill_type((*field)->type()); 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (autofill_type.group() == AutoFillType::CREDIT_CARD) 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->has_credit_card_field_ = true; 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (autofill_type.field_type() != UNKNOWN_TYPE) 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->has_autofillable_field_ = true; 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++current_type; 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form->UpdateAutoFillCount(); 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string FormStructure::FormSignature() const { 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string form_string = target_url_.scheme() + 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "://" + 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch target_url_.host() + 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "&" + 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UTF16ToUTF8(form_name_) + 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form_signature_field_names_; 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return Hash64Bit(form_string); 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochbool FormStructure::IsAutoFillable(bool require_method_post) const { 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (autofill_count() < kRequiredFillableFields) 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2624a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return ShouldBeParsed(require_method_post); 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool FormStructure::HasAutoFillableValues() const { 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (autofill_count_ == 0) 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (std::vector<AutoFillField*>::const_iterator iter = begin(); 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch iter != end(); ++iter) { 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AutoFillField* field = *iter; 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (field && !field->IsEmpty() && field->IsFieldFillable()) 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FormStructure::UpdateAutoFillCount() { 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch autofill_count_ = 0; 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (std::vector<AutoFillField*>::const_iterator iter = begin(); 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch iter != end(); ++iter) { 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AutoFillField* field = *iter; 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (field && field->IsFieldFillable()) 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++autofill_count_; 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochbool FormStructure::ShouldBeParsed(bool require_method_post) const { 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (field_count() < kRequiredFillableFields) 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Rule out http(s)://*/search?... 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // e.g. http://www.google.com/search?q=... 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // http://search.yahoo.com/search?p=... 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (target_url_.path() == "/search") 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return !require_method_post || (method_ == POST); 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FormStructure::set_possible_types(int index, const FieldTypeSet& types) { 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int num_fields = static_cast<int>(field_count()); 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(index >= 0 && index < num_fields); 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (index >= 0 && index < num_fields) 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch fields_[index]->set_possible_types(types); 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst AutoFillField* FormStructure::field(int index) const { 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return fields_[index]; 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochsize_t FormStructure::field_count() const { 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Don't count the NULL terminator. 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t field_size = fields_.size(); 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (field_size == 0) ? 0 : field_size - 1; 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool FormStructure::operator==(const FormData& form) const { 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(jhawkins): Is this enough to differentiate a form? 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (form_name_ == form.name && 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch source_url_ == form.origin && 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch target_url_ == form.action) { 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(jhawkins): Compare field names, IDs and labels once we have labels 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // set up. 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool FormStructure::operator!=(const FormData& form) const { 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return !operator==(form); 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FormStructure::GetHeuristicAutoFillTypes() { 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch has_credit_card_field_ = false; 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch has_autofillable_field_ = false; 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FieldTypeMap field_type_map; 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetHeuristicFieldInfo(&field_type_map); 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t index = 0; index < field_count(); index++) { 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AutoFillField* field = fields_[index]; 3463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(field); 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FieldTypeMap::iterator iter = field_type_map.find(field->unique_name()); 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AutoFillFieldType heuristic_auto_fill_type; 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (iter == field_type_map.end()) { 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch heuristic_auto_fill_type = UNKNOWN_TYPE; 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch heuristic_auto_fill_type = iter->second; 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++autofill_count_; 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch field->set_heuristic_type(heuristic_auto_fill_type); 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AutoFillType autofill_type(field->type()); 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (autofill_type.group() == AutoFillType::CREDIT_CARD) 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch has_credit_card_field_ = true; 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (autofill_type.field_type() != UNKNOWN_TYPE) 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch has_autofillable_field_ = true; 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FormStructure::GetHeuristicFieldInfo(FieldTypeMap* field_type_map) { 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FormFieldSet fields(this); 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FormFieldSet::const_iterator field; 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (field = fields.begin(); field != fields.end(); field++) { 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool ok = (*field)->GetFieldInfo(field_type_map); 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(ok); 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool FormStructure::EncodeFormRequest( 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FormStructure::EncodeRequestType request_type, 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buzz::XmlElement* encompassing_xml_element) const { 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!field_count()) // Nothing to add. 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 382513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Some badly formatted web sites repeat fields - limit number of fields to 383513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // 48, which is far larger than any valid form and XML still fits into 2K. 384513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const size_t kMaxFieldsOnTheForm = 48; 385513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (field_count() > kMaxFieldsOnTheForm) { 386513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // This is not a valid form, most certainly. Do not send request for the 387513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // wrongly formatted forms. 388513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 389513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add the child nodes for the form fields. 391513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (size_t index = 0; index < field_count(); ++index) { 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const AutoFillField* field = fields_[index]; 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (request_type == FormStructure::UPLOAD) { 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FieldTypeSet types = field->possible_types(); 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (FieldTypeSet::const_iterator type = types.begin(); 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch type != types.end(); type++) { 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buzz::XmlElement *field_element = new buzz::XmlElement( 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buzz::QName(kXMLElementField)); 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch field_element->SetAttr(buzz::QName(kAttributeSignature), 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch field->FieldSignature()); 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch field_element->SetAttr(buzz::QName(kAttributeAutoFillType), 4033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::IntToString(*type)); 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch encompassing_xml_element->AddElement(field_element); 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buzz::XmlElement *field_element = new buzz::XmlElement( 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buzz::QName(kXMLElementField)); 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch field_element->SetAttr(buzz::QName(kAttributeSignature), 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch field->FieldSignature()); 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch encompassing_xml_element->AddElement(field_element); 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 416