| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <vector> | 5 #include <vector> |
| 6 | 6 |
| 7 #include "base/format_macros.h" | 7 #include "base/format_macros.h" |
| 8 #include "base/string16.h" | 8 #include "base/string16.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 | 157 |
| 158 WebElement web_element = frame->document().getElementById("element"); | 158 WebElement web_element = frame->document().getElementById("element"); |
| 159 WebFormControlElement element = web_element.to<WebFormControlElement>(); | 159 WebFormControlElement element = web_element.to<WebFormControlElement>(); |
| 160 FormFieldData result; | 160 FormFieldData result; |
| 161 WebFormControlElementToFormField(element, autofill::EXTRACT_VALUE, &result); | 161 WebFormControlElementToFormField(element, autofill::EXTRACT_VALUE, &result); |
| 162 | 162 |
| 163 FormFieldData expected; | 163 FormFieldData expected; |
| 164 expected.name = ASCIIToUTF16("element"); | 164 expected.name = ASCIIToUTF16("element"); |
| 165 expected.value = ASCIIToUTF16("value"); | 165 expected.value = ASCIIToUTF16("value"); |
| 166 expected.form_control_type = ASCIIToUTF16("text"); | 166 expected.form_control_type = ASCIIToUTF16("text"); |
| 167 expected.autocomplete_attribute = ASCIIToUTF16("off"); |
| 167 expected.max_length = WebInputElement::defaultMaxLength(); | 168 expected.max_length = WebInputElement::defaultMaxLength(); |
| 168 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result); | 169 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result); |
| 169 } | 170 } |
| 170 | 171 |
| 171 // We should be able to extract a text field with maxlength specified. | 172 // We should be able to extract a text field with maxlength specified. |
| 172 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldMaxLength) { | 173 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldMaxLength) { |
| 173 LoadHTML("<INPUT type=\"text\" id=\"element\" value=\"value\"" | 174 LoadHTML("<INPUT type=\"text\" id=\"element\" value=\"value\"" |
| 174 " maxlength=\"5\"/>"); | 175 " maxlength=\"5\"/>"); |
| 175 | 176 |
| 176 WebFrame* frame = GetMainFrame(); | 177 WebFrame* frame = GetMainFrame(); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 WebFormControlElementToFormField(element, autofill::EXTRACT_VALUE, &result); | 310 WebFormControlElementToFormField(element, autofill::EXTRACT_VALUE, &result); |
| 310 expected.name = ASCIIToUTF16("submit"); | 311 expected.name = ASCIIToUTF16("submit"); |
| 311 expected.form_control_type = ASCIIToUTF16("submit"); | 312 expected.form_control_type = ASCIIToUTF16("submit"); |
| 312 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result); | 313 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result); |
| 313 } | 314 } |
| 314 | 315 |
| 315 // We should be able to extract the autocompletetype attribute. | 316 // We should be able to extract the autocompletetype attribute. |
| 316 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldAutocompletetype) { | 317 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldAutocompletetype) { |
| 317 std::string html = | 318 std::string html = |
| 318 "<INPUT type=\"text\" id=\"absent\"/>" | 319 "<INPUT type=\"text\" id=\"absent\"/>" |
| 319 "<INPUT type=\"text\" id=\"empty\" x-autocompletetype=\"\"/>" | 320 "<INPUT type=\"text\" id=\"empty\" autocomplete=\"\"/>" |
| 320 "<INPUT type=\"text\" id=\"whitespace\" x-autocompletetype=\" \"/>" | 321 "<INPUT type=\"text\" id=\"off\" autocomplete=\"off\"/>" |
| 321 "<INPUT type=\"text\" id=\"regular\" x-autocompletetype=\"email\"/>" | 322 "<INPUT type=\"text\" id=\"regular\" autocomplete=\"email\"/>" |
| 322 "<INPUT type=\"text\" id=\"multi-valued\" " | 323 "<INPUT type=\"text\" id=\"multi-valued\" " |
| 323 " x-autocompletetype=\"x-confirm-email email\"/>" | 324 " autocomplete=\"billing email\"/>" |
| 324 "<INPUT type=\"text\" id=\"unprefixed\" autocompletetype=\"email\"/>" | 325 "<INPUT type=\"text\" id=\"experimental\" x-autocompletetype=\"email\"/>" |
| 325 "<SELECT id=\"select\" x-autocompletetype=\"state\"/>" | 326 "<SELECT id=\"select\" autocomplete=\"state\"/>" |
| 326 " <OPTION value=\"CA\">California</OPTION>" | 327 " <OPTION value=\"CA\">California</OPTION>" |
| 327 " <OPTION value=\"TX\">Texas</OPTION>" | 328 " <OPTION value=\"TX\">Texas</OPTION>" |
| 328 "</SELECT>"; | 329 "</SELECT>"; |
| 329 html += | 330 html += |
| 330 "<INPUT type=\"text\" id=\"malicious\" x-autocompletetype=\"" + | 331 "<INPUT type=\"text\" id=\"malicious\" autocomplete=\"" + |
| 331 std::string(10000, 'x') + "\"/>"; | 332 std::string(10000, 'x') + "\"/>"; |
| 332 LoadHTML(html.c_str()); | 333 LoadHTML(html.c_str()); |
| 333 | 334 |
| 334 WebFrame* frame = GetMainFrame(); | 335 WebFrame* frame = GetMainFrame(); |
| 335 ASSERT_NE(static_cast<WebFrame*>(NULL), frame); | 336 ASSERT_NE(static_cast<WebFrame*>(NULL), frame); |
| 336 | 337 |
| 337 // An absent attribute is equivalent to an empty one. | 338 struct TestCase { |
| 338 WebElement web_element = frame->document().getElementById("absent"); | 339 const std::string element_id; |
| 339 WebFormControlElement element = web_element.to<WebFormControlElement>(); | 340 const std::string form_control_type; |
| 340 FormFieldData result1; | 341 const std::string autocomplete_attribute; |
| 341 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result1); | 342 }; |
| 343 TestCase test_cases[] = { |
| 344 // An absent attribute is equivalent to an empty one. |
| 345 { "absent", "text", "" }, |
| 346 // Make sure there are no issues parsing an empty attribute. |
| 347 { "empty", "text", "" }, |
| 348 // Make sure there are no issues parsing an attribute value that isn't a |
| 349 // type hint. |
| 350 { "off", "text", "off" }, |
| 351 // Common case: exactly one type specified. |
| 352 { "regular", "text", "email" }, |
| 353 // Verify that we correctly extract multiple tokens as well. |
| 354 { "multi-valued", "text", "billing email" }, |
| 355 // We previously extracted this data from the experimental |
| 356 // 'x-autocompletetype' attribute. Now that the field type hints are part |
| 357 // of the spec under the autocomplete attribute, we no longer support the |
| 358 // experimental version. |
| 359 { "experimental", "text", "" }, |
| 360 // <select> elements should behave no differently from text fields here. |
| 361 { "select", "select-one", "state" }, |
| 362 // Very long attribute values should be replaced by a default string, to |
| 363 // prevent malicious websites from DOSing the browser process. |
| 364 { "malicious", "text", "x-max-data-length-exceeded" }, |
| 365 }; |
| 342 | 366 |
| 343 FormFieldData expected; | 367 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { |
| 344 expected.name = ASCIIToUTF16("absent"); | 368 WebElement web_element = frame->document().getElementById( |
| 345 expected.form_control_type = ASCIIToUTF16("text"); | 369 ASCIIToUTF16(test_cases[i].element_id)); |
| 346 expected.autocomplete_type = string16(); | 370 WebFormControlElement element = web_element.to<WebFormControlElement>(); |
| 347 expected.max_length = WebInputElement::defaultMaxLength(); | 371 FormFieldData result; |
| 348 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result1); | 372 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result); |
| 349 | 373 |
| 350 web_element = frame->document().getElementById("empty"); | 374 FormFieldData expected; |
| 351 element = web_element.to<WebFormControlElement>(); | 375 expected.name = ASCIIToUTF16(test_cases[i].element_id); |
| 352 FormFieldData result2; | 376 expected.form_control_type = ASCIIToUTF16(test_cases[i].form_control_type); |
| 353 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result2); | 377 expected.autocomplete_attribute = |
| 354 expected.name = ASCIIToUTF16("empty"); | 378 ASCIIToUTF16(test_cases[i].autocomplete_attribute); |
| 355 expected.form_control_type = ASCIIToUTF16("text"); | 379 if (test_cases[i].form_control_type == "text") |
| 356 expected.autocomplete_type = string16(); | 380 expected.max_length = WebInputElement::defaultMaxLength(); |
| 357 expected.max_length = WebInputElement::defaultMaxLength(); | 381 else |
| 358 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result2); | 382 expected.max_length = 0; |
| 359 | 383 |
| 360 // The renderer should trim whitespace. | 384 SCOPED_TRACE(test_cases[i].element_id); |
| 361 web_element = frame->document().getElementById("whitespace"); | 385 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result); |
| 362 element = web_element.to<WebFormControlElement>(); | 386 } |
| 363 FormFieldData result3; | |
| 364 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result3); | |
| 365 expected.name = ASCIIToUTF16("whitespace"); | |
| 366 expected.form_control_type = ASCIIToUTF16("text"); | |
| 367 expected.autocomplete_type = string16(); | |
| 368 expected.max_length = WebInputElement::defaultMaxLength(); | |
| 369 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result3); | |
| 370 | |
| 371 // Common case: exactly one type specified. | |
| 372 web_element = frame->document().getElementById("regular"); | |
| 373 element = web_element.to<WebFormControlElement>(); | |
| 374 FormFieldData result4; | |
| 375 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result4); | |
| 376 expected.name = ASCIIToUTF16("regular"); | |
| 377 expected.form_control_type = ASCIIToUTF16("text"); | |
| 378 expected.autocomplete_type = ASCIIToUTF16("email"); | |
| 379 expected.max_length = WebInputElement::defaultMaxLength(); | |
| 380 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result4); | |
| 381 | |
| 382 // Verify that we correctly extract fallback types as well. | |
| 383 web_element = frame->document().getElementById("multi-valued"); | |
| 384 element = web_element.to<WebFormControlElement>(); | |
| 385 FormFieldData result5; | |
| 386 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result5); | |
| 387 expected.name = ASCIIToUTF16("multi-valued"); | |
| 388 expected.form_control_type = ASCIIToUTF16("text"); | |
| 389 expected.autocomplete_type = ASCIIToUTF16("x-confirm-email email"); | |
| 390 expected.max_length = WebInputElement::defaultMaxLength(); | |
| 391 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result5); | |
| 392 | |
| 393 // The attribute is not yet part of the HTML standard, so we only recognize | |
| 394 // the prefixed version -- 'x-autocompletetype' -- and not the unprefixed one. | |
| 395 web_element = frame->document().getElementById("unprefixed"); | |
| 396 element = web_element.to<WebFormControlElement>(); | |
| 397 FormFieldData result6; | |
| 398 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result6); | |
| 399 expected.name = ASCIIToUTF16("unprefixed"); | |
| 400 expected.form_control_type = ASCIIToUTF16("text"); | |
| 401 expected.autocomplete_type = string16(); | |
| 402 expected.max_length = WebInputElement::defaultMaxLength(); | |
| 403 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result6); | |
| 404 | |
| 405 // <select> elements should behave no differently from text fields here. | |
| 406 web_element = frame->document().getElementById("select"); | |
| 407 element = web_element.to<WebFormControlElement>(); | |
| 408 FormFieldData result7; | |
| 409 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result7); | |
| 410 expected.name = ASCIIToUTF16("select"); | |
| 411 expected.form_control_type = ASCIIToUTF16("select-one"); | |
| 412 expected.autocomplete_type = ASCIIToUTF16("state"); | |
| 413 expected.max_length = 0; | |
| 414 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result7); | |
| 415 | |
| 416 // Very long attribute values should be replaced by a default string, to | |
| 417 // prevent malicious websites from DOSing the browser process. | |
| 418 web_element = frame->document().getElementById("malicious"); | |
| 419 element = web_element.to<WebFormControlElement>(); | |
| 420 FormFieldData result8; | |
| 421 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result8); | |
| 422 expected.name = ASCIIToUTF16("malicious"); | |
| 423 expected.form_control_type = ASCIIToUTF16("text"); | |
| 424 expected.autocomplete_type = ASCIIToUTF16("x-max-data-length-exceeded"); | |
| 425 expected.max_length = WebInputElement::defaultMaxLength(); | |
| 426 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result8); | |
| 427 } | 387 } |
| 428 | 388 |
| 429 TEST_F(FormAutofillTest, WebFormElementToFormData) { | 389 TEST_F(FormAutofillTest, WebFormElementToFormData) { |
| 430 LoadHTML("<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">" | 390 LoadHTML("<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">" |
| 431 " <LABEL for=\"firstname\">First name:</LABEL>" | 391 " <LABEL for=\"firstname\">First name:</LABEL>" |
| 432 " <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>" | 392 " <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>" |
| 433 " <LABEL for=\"lastname\">Last name:</LABEL>" | 393 " <LABEL for=\"lastname\">Last name:</LABEL>" |
| 434 " <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>" | 394 " <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>" |
| 435 " <LABEL for=\"state\">State:</LABEL>" | 395 " <LABEL for=\"state\">State:</LABEL>" |
| 436 " <SELECT id=\"state\"/>" | 396 " <SELECT id=\"state\"/>" |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 739 expected.value = ASCIIToUTF16("John"); | 699 expected.value = ASCIIToUTF16("John"); |
| 740 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]); | 700 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]); |
| 741 EXPECT_FORM_FIELD_DATA_EQUALS(expected, field); | 701 EXPECT_FORM_FIELD_DATA_EQUALS(expected, field); |
| 742 | 702 |
| 743 expected.name = ASCIIToUTF16("lastname"); | 703 expected.name = ASCIIToUTF16("lastname"); |
| 744 expected.value = ASCIIToUTF16("Smith"); | 704 expected.value = ASCIIToUTF16("Smith"); |
| 745 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]); | 705 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]); |
| 746 | 706 |
| 747 expected.name = ASCIIToUTF16("email"); | 707 expected.name = ASCIIToUTF16("email"); |
| 748 expected.value = ASCIIToUTF16("john@example.com"); | 708 expected.value = ASCIIToUTF16("john@example.com"); |
| 709 expected.autocomplete_attribute = ASCIIToUTF16("off"); |
| 749 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]); | 710 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]); |
| 750 | 711 |
| 751 expected.name = ASCIIToUTF16("phone"); | 712 expected.name = ASCIIToUTF16("phone"); |
| 752 expected.value = ASCIIToUTF16("1.800.555.1234"); | 713 expected.value = ASCIIToUTF16("1.800.555.1234"); |
| 714 expected.autocomplete_attribute = string16(); |
| 753 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[3]); | 715 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[3]); |
| 754 | 716 |
| 755 // Try again, but require autocomplete. | 717 // Try again, but require autocomplete. |
| 756 FormData form2; | 718 FormData form2; |
| 757 FormFieldData field2; | 719 FormFieldData field2; |
| 758 EXPECT_TRUE(FindFormAndFieldForInputElement(input_element, &form2, &field2, | 720 EXPECT_TRUE(FindFormAndFieldForInputElement(input_element, &form2, &field2, |
| 759 autofill::REQUIRE_AUTOCOMPLETE)); | 721 autofill::REQUIRE_AUTOCOMPLETE)); |
| 760 EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name); | 722 EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name); |
| 761 EXPECT_EQ(GURL(web_frame->document().url()), form2.origin); | 723 EXPECT_EQ(GURL(web_frame->document().url()), form2.origin); |
| 762 EXPECT_EQ(GURL("http://buh.com"), form2.action); | 724 EXPECT_EQ(GURL("http://buh.com"), form2.action); |
| (...skipping 1726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2489 expected.name = ASCIIToUTF16("firstname"); | 2451 expected.name = ASCIIToUTF16("firstname"); |
| 2490 expected.value = string16(); | 2452 expected.value = string16(); |
| 2491 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]); | 2453 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]); |
| 2492 | 2454 |
| 2493 expected.name = ASCIIToUTF16("lastname"); | 2455 expected.name = ASCIIToUTF16("lastname"); |
| 2494 expected.value = string16(); | 2456 expected.value = string16(); |
| 2495 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]); | 2457 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]); |
| 2496 | 2458 |
| 2497 expected.name = ASCIIToUTF16("noAC"); | 2459 expected.name = ASCIIToUTF16("noAC"); |
| 2498 expected.value = string16(); | 2460 expected.value = string16(); |
| 2461 expected.autocomplete_attribute = ASCIIToUTF16("off"); |
| 2499 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]); | 2462 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]); |
| 2500 | 2463 |
| 2501 expected.name = ASCIIToUTF16("notenabled"); | 2464 expected.name = ASCIIToUTF16("notenabled"); |
| 2502 expected.value = ASCIIToUTF16("no clear"); | 2465 expected.value = ASCIIToUTF16("no clear"); |
| 2466 expected.autocomplete_attribute = string16(); |
| 2503 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[3]); | 2467 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[3]); |
| 2504 | 2468 |
| 2505 // Verify that the cursor position has been updated. | 2469 // Verify that the cursor position has been updated. |
| 2506 EXPECT_EQ(0, firstname.selectionStart()); | 2470 EXPECT_EQ(0, firstname.selectionStart()); |
| 2507 EXPECT_EQ(0, firstname.selectionEnd()); | 2471 EXPECT_EQ(0, firstname.selectionEnd()); |
| 2508 } | 2472 } |
| 2509 | 2473 |
| 2510 TEST_F(FormAutofillTest, ClearFormWithNodeContainingSelectOne) { | 2474 TEST_F(FormAutofillTest, ClearFormWithNodeContainingSelectOne) { |
| 2511 LoadHTML( | 2475 LoadHTML( |
| 2512 "<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">" | 2476 "<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">" |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2931 expected.form_control_type = ASCIIToUTF16("text"); | 2895 expected.form_control_type = ASCIIToUTF16("text"); |
| 2932 expected.max_length = WebInputElement::defaultMaxLength(); | 2896 expected.max_length = WebInputElement::defaultMaxLength(); |
| 2933 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]); | 2897 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]); |
| 2934 | 2898 |
| 2935 expected.name = ASCIIToUTF16("country"); | 2899 expected.name = ASCIIToUTF16("country"); |
| 2936 expected.value = ASCIIToUTF16("AL"); | 2900 expected.value = ASCIIToUTF16("AL"); |
| 2937 expected.form_control_type = ASCIIToUTF16("select-one"); | 2901 expected.form_control_type = ASCIIToUTF16("select-one"); |
| 2938 expected.max_length = 0; | 2902 expected.max_length = 0; |
| 2939 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]); | 2903 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]); |
| 2940 } | 2904 } |
| OLD | NEW |