| OLD | NEW |
| 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/content/renderer/password_form_conversion_utils.h" | 5 #include "components/autofill/content/renderer/password_form_conversion_utils.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/metrics/histogram_macros.h" | 11 #include "base/metrics/histogram_macros.h" |
| 12 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
| 13 #include "components/autofill/content/renderer/form_autofill_util.h" | 13 #include "components/autofill/content/renderer/form_autofill_util.h" |
| 14 #include "components/autofill/core/common/form_data_predictions.h" | |
| 15 #include "components/autofill/core/common/password_form.h" | 14 #include "components/autofill/core/common/password_form.h" |
| 15 #include "components/autofill/core/common/password_form_field_prediction_map.h" |
| 16 #include "third_party/WebKit/public/platform/WebString.h" | 16 #include "third_party/WebKit/public/platform/WebString.h" |
| 17 #include "third_party/WebKit/public/web/WebDocument.h" | 17 #include "third_party/WebKit/public/web/WebDocument.h" |
| 18 #include "third_party/WebKit/public/web/WebFormControlElement.h" | 18 #include "third_party/WebKit/public/web/WebFormControlElement.h" |
| 19 #include "third_party/WebKit/public/web/WebInputElement.h" | 19 #include "third_party/WebKit/public/web/WebInputElement.h" |
| 20 #include "third_party/icu/source/i18n/unicode/regex.h" | 20 #include "third_party/icu/source/i18n/unicode/regex.h" |
| 21 | 21 |
| 22 using blink::WebDocument; | 22 using blink::WebDocument; |
| 23 using blink::WebFormControlElement; | 23 using blink::WebFormControlElement; |
| 24 using blink::WebFormElement; | 24 using blink::WebFormElement; |
| 25 using blink::WebInputElement; | 25 using blink::WebInputElement; |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 *new_password = passwords[0]; | 174 *new_password = passwords[0]; |
| 175 } else { | 175 } else { |
| 176 // Three different passwords, or first and last match with middle | 176 // Three different passwords, or first and last match with middle |
| 177 // different. No idea which is which, so no luck. | 177 // different. No idea which is which, so no luck. |
| 178 return false; | 178 return false; |
| 179 } | 179 } |
| 180 } | 180 } |
| 181 return true; | 181 return true; |
| 182 } | 182 } |
| 183 | 183 |
| 184 void FindPredictedUsernameElement( | 184 void FindPredictedElements( |
| 185 const WebFormElement& form, | 185 const WebFormElement& form, |
| 186 const std::map<autofill::FormData, autofill::FormFieldData>& | 186 const std::map<autofill::FormData, |
| 187 form_predictions, | 187 autofill::PasswordFormFieldPredictionMap>& form_predictions, |
| 188 WebVector<WebFormControlElement>* control_elements, | 188 WebVector<WebFormControlElement>* control_elements, |
| 189 WebInputElement* predicted_username_element) { | 189 std::map<autofill::PasswordFormFieldPredictionType, WebInputElement>* |
| 190 predicted_elements) { |
| 190 FormData form_data; | 191 FormData form_data; |
| 191 if (!WebFormElementToFormData(form, WebFormControlElement(), EXTRACT_NONE, | 192 if (!WebFormElementToFormData(form, WebFormControlElement(), EXTRACT_NONE, |
| 192 &form_data, nullptr)) { | 193 &form_data, nullptr)) { |
| 193 return; | 194 return; |
| 194 } | 195 } |
| 195 | 196 |
| 196 // Matching only requires that action and name of the form match to allow | 197 // Matching only requires that action and name of the form match to allow |
| 197 // the username to be updated even if the form is changed after page load. | 198 // the username to be updated even if the form is changed after page load. |
| 198 // See https://crbug.com/476092 for more details. | 199 // See https://crbug.com/476092 for more details. |
| 199 auto predictions_iterator = form_predictions.begin(); | 200 auto predictions_iterator = form_predictions.begin(); |
| 200 for (;predictions_iterator != form_predictions.end(); | 201 for (;predictions_iterator != form_predictions.end(); |
| 201 ++predictions_iterator) { | 202 ++predictions_iterator) { |
| 202 if (predictions_iterator->first.action == form_data.action && | 203 if (predictions_iterator->first.action == form_data.action && |
| 203 predictions_iterator->first.name == form_data.name) { | 204 predictions_iterator->first.name == form_data.name) { |
| 204 break; | 205 break; |
| 205 } | 206 } |
| 206 } | 207 } |
| 207 | 208 |
| 208 if (predictions_iterator == form_predictions.end()) | 209 if (predictions_iterator == form_predictions.end()) |
| 209 return; | 210 return; |
| 210 | 211 |
| 211 std::vector<blink::WebFormControlElement> autofillable_elements = | 212 std::vector<blink::WebFormControlElement> autofillable_elements = |
| 212 ExtractAutofillableElementsFromSet(*control_elements); | 213 ExtractAutofillableElementsFromSet(*control_elements); |
| 213 | 214 |
| 214 const autofill::FormFieldData& username_field = predictions_iterator->second; | 215 const autofill::PasswordFormFieldPredictionMap& field_predictions = |
| 215 for (size_t i = 0; i < autofillable_elements.size(); ++i) { | 216 predictions_iterator->second; |
| 216 if (autofillable_elements[i].nameForAutofill() == username_field.name) { | 217 for (autofill::PasswordFormFieldPredictionMap::const_iterator prediction = |
| 217 WebInputElement* input_element = | 218 field_predictions.begin(); |
| 218 toWebInputElement(&autofillable_elements[i]); | 219 prediction != field_predictions.end(); ++prediction) { |
| 219 if (input_element) { | 220 const autofill::PasswordFormFieldPredictionType& type = prediction->first; |
| 220 *predicted_username_element = *input_element; | 221 const autofill::FormFieldData& target_field = prediction->second; |
| 222 |
| 223 for (size_t i = 0; i < autofillable_elements.size(); ++i) { |
| 224 if (autofillable_elements[i].nameForAutofill() == target_field.name) { |
| 225 WebInputElement* input_element = |
| 226 toWebInputElement(&autofillable_elements[i]); |
| 227 if (input_element) { |
| 228 (*predicted_elements)[type] = *input_element; |
| 229 } |
| 230 break; |
| 221 } | 231 } |
| 222 break; | |
| 223 } | 232 } |
| 224 } | 233 } |
| 225 } | 234 } |
| 226 | 235 |
| 227 // Get information about a login form encapsulated in a PasswordForm struct. | 236 // Get information about a login form encapsulated in a PasswordForm struct. |
| 228 // If an element of |form| has an entry in |nonscript_modified_values|, the | 237 // If an element of |form| has an entry in |nonscript_modified_values|, the |
| 229 // associated string is used instead of the element's value to create | 238 // associated string is used instead of the element's value to create |
| 230 // the PasswordForm. | 239 // the PasswordForm. |
| 231 void GetPasswordForm( | 240 void GetPasswordForm( |
| 232 const WebFormElement& form, | 241 const WebFormElement& form, |
| 233 PasswordForm* password_form, | 242 PasswordForm* password_form, |
| 234 const std::map<const blink::WebInputElement, blink::WebString>* | 243 const std::map<const blink::WebInputElement, blink::WebString>* |
| 235 nonscript_modified_values, | 244 nonscript_modified_values, |
| 236 const std::map<autofill::FormData, autofill::FormFieldData>* | 245 const std::map<autofill::FormData, |
| 246 autofill::PasswordFormFieldPredictionMap>* |
| 237 form_predictions) { | 247 form_predictions) { |
| 238 WebInputElement latest_input_element; | 248 WebInputElement latest_input_element; |
| 239 WebInputElement username_element; | 249 WebInputElement username_element; |
| 240 password_form->username_marked_by_site = false; | 250 password_form->username_marked_by_site = false; |
| 241 std::vector<WebInputElement> passwords; | 251 std::vector<WebInputElement> passwords; |
| 242 std::vector<base::string16> other_possible_usernames; | 252 std::vector<base::string16> other_possible_usernames; |
| 243 | 253 |
| 244 WebVector<WebFormControlElement> control_elements; | 254 WebVector<WebFormControlElement> control_elements; |
| 245 form.getFormControlElements(control_elements); | 255 form.getFormControlElements(control_elements); |
| 246 | 256 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 if (username_element.isNull()) | 339 if (username_element.isNull()) |
| 330 latest_input_element = *input_element; | 340 latest_input_element = *input_element; |
| 331 if (!input_element->value().isEmpty()) | 341 if (!input_element->value().isEmpty()) |
| 332 other_possible_usernames.push_back(input_element->value()); | 342 other_possible_usernames.push_back(input_element->value()); |
| 333 } | 343 } |
| 334 } | 344 } |
| 335 } | 345 } |
| 336 } | 346 } |
| 337 password_form->layout = SequenceToLayout(layout_sequence); | 347 password_form->layout = SequenceToLayout(layout_sequence); |
| 338 | 348 |
| 339 WebInputElement predicted_username_element; | 349 std::map<autofill::PasswordFormFieldPredictionType, WebInputElement> |
| 350 predicted_elements; |
| 340 if (form_predictions) { | 351 if (form_predictions) { |
| 341 FindPredictedUsernameElement(form, *form_predictions, &control_elements, | 352 FindPredictedElements(form, *form_predictions, &control_elements, |
| 342 &predicted_username_element); | 353 &predicted_elements); |
| 343 } | 354 } |
| 344 // Let server predictions override the selection of the username field. This | 355 // Let server predictions override the selection of the username field. This |
| 345 // allows instant adjusting without changing Chromium code. | 356 // allows instant adjusting without changing Chromium code. |
| 346 if (!predicted_username_element.isNull() && | 357 if (!predicted_elements[autofill::PREDICTION_USERNAME].isNull() && |
| 347 username_element != predicted_username_element) { | 358 username_element != predicted_elements[autofill::PREDICTION_USERNAME]) { |
| 348 auto it = | 359 auto it = |
| 349 find(other_possible_usernames.begin(), other_possible_usernames.end(), | 360 find(other_possible_usernames.begin(), other_possible_usernames.end(), |
| 350 predicted_username_element.value()); | 361 predicted_elements[autofill::PREDICTION_USERNAME].value()); |
| 351 if (it != other_possible_usernames.end()) | 362 if (it != other_possible_usernames.end()) |
| 352 other_possible_usernames.erase(it); | 363 other_possible_usernames.erase(it); |
| 353 if (!username_element.isNull()) { | 364 if (!username_element.isNull()) { |
| 354 other_possible_usernames.push_back(username_element.value()); | 365 other_possible_usernames.push_back(username_element.value()); |
| 355 } | 366 } |
| 356 username_element = predicted_username_element; | 367 username_element = predicted_elements[autofill::PREDICTION_USERNAME]; |
| 357 password_form->was_parsed_using_autofill_predictions = true; | 368 password_form->was_parsed_using_autofill_predictions = true; |
| 358 } | 369 } |
| 359 | 370 |
| 360 if (!username_element.isNull()) { | 371 if (!username_element.isNull()) { |
| 361 password_form->username_element = username_element.nameForAutofill(); | 372 password_form->username_element = username_element.nameForAutofill(); |
| 362 base::string16 username_value = username_element.value(); | 373 base::string16 username_value = username_element.value(); |
| 363 if (nonscript_modified_values != nullptr) { | 374 if (nonscript_modified_values != nullptr) { |
| 364 auto username_iterator = | 375 auto username_iterator = |
| 365 nonscript_modified_values->find(username_element); | 376 nonscript_modified_values->find(username_element); |
| 366 if (username_iterator != nonscript_modified_values->end()) { | 377 if (username_iterator != nonscript_modified_values->end()) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 | 459 |
| 449 GURL GetCanonicalOriginForDocument(const WebDocument& document) { | 460 GURL GetCanonicalOriginForDocument(const WebDocument& document) { |
| 450 GURL full_origin(document.url()); | 461 GURL full_origin(document.url()); |
| 451 return StripAuthAndParams(full_origin); | 462 return StripAuthAndParams(full_origin); |
| 452 } | 463 } |
| 453 | 464 |
| 454 scoped_ptr<PasswordForm> CreatePasswordForm( | 465 scoped_ptr<PasswordForm> CreatePasswordForm( |
| 455 const WebFormElement& web_form, | 466 const WebFormElement& web_form, |
| 456 const std::map<const blink::WebInputElement, blink::WebString>* | 467 const std::map<const blink::WebInputElement, blink::WebString>* |
| 457 nonscript_modified_values, | 468 nonscript_modified_values, |
| 458 const std::map<autofill::FormData, autofill::FormFieldData>* | 469 const std::map<autofill::FormData, |
| 470 autofill::PasswordFormFieldPredictionMap>* |
| 459 form_predictions) { | 471 form_predictions) { |
| 460 if (web_form.isNull()) | 472 if (web_form.isNull()) |
| 461 return scoped_ptr<PasswordForm>(); | 473 return scoped_ptr<PasswordForm>(); |
| 462 | 474 |
| 463 scoped_ptr<PasswordForm> password_form(new PasswordForm()); | 475 scoped_ptr<PasswordForm> password_form(new PasswordForm()); |
| 464 GetPasswordForm(web_form, password_form.get(), nonscript_modified_values, | 476 GetPasswordForm(web_form, password_form.get(), nonscript_modified_values, |
| 465 form_predictions); | 477 form_predictions); |
| 466 | 478 |
| 467 if (!password_form->action.is_valid()) | 479 if (!password_form->action.is_valid()) |
| 468 return scoped_ptr<PasswordForm>(); | 480 return scoped_ptr<PasswordForm>(); |
| 469 | 481 |
| 470 WebFormElementToFormData(web_form, | 482 WebFormElementToFormData(web_form, |
| 471 blink::WebFormControlElement(), | 483 blink::WebFormControlElement(), |
| 472 EXTRACT_NONE, | 484 EXTRACT_NONE, |
| 473 &password_form->form_data, | 485 &password_form->form_data, |
| 474 NULL /* FormFieldData */); | 486 NULL /* FormFieldData */); |
| 475 | 487 |
| 476 return password_form.Pass(); | 488 return password_form.Pass(); |
| 477 } | 489 } |
| 478 | 490 |
| 479 } // namespace autofill | 491 } // namespace autofill |
| OLD | NEW |