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 "url/url_parse.h" | 5 #include "url/third_party/mozilla/url_parse.h" |
6 | 6 |
7 #include "base/macros.h" | 7 #include "base/macros.h" |
8 #include "testing/gtest/include/gtest/gtest.h" | 8 #include "testing/gtest/include/gtest/gtest.h" |
9 #include "url/url_parse.h" | 9 #include "url/third_party/mozilla/url_parse.h" |
10 | 10 |
11 // Interesting IE file:isms... | 11 // Interesting IE file:isms... |
12 // | 12 // |
13 // file:/foo/bar file:///foo/bar | 13 // file:/foo/bar file:///foo/bar |
14 // The result here seems totally invalid!?!? This isn't UNC. | 14 // The result here seems totally invalid!?!? This isn't UNC. |
15 // | 15 // |
16 // file:/ | 16 // file:/ |
17 // file:// or any other number of slashes | 17 // file:// or any other number of slashes |
18 // IE6 doesn't do anything at all if you click on this link. No error: | 18 // IE6 doesn't do anything at all if you click on this link. No error: |
19 // nothing. IE6's history system seems to always color this link, so I'm | 19 // nothing. IE6's history system seems to always color this link, so I'm |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 int inner_port; | 83 int inner_port; |
84 const char* inner_path; | 84 const char* inner_path; |
85 const char* path; | 85 const char* path; |
86 const char* query; | 86 const char* query; |
87 const char* ref; | 87 const char* ref; |
88 }; | 88 }; |
89 | 89 |
90 bool ComponentMatches(const char* input, | 90 bool ComponentMatches(const char* input, |
91 const char* reference, | 91 const char* reference, |
92 const Component& component) { | 92 const Component& component) { |
93 // If the component is nonexistant (length == -1), it should begin at 0. | 93 // If the component is nonexistent (length == -1), it should begin at 0. |
94 EXPECT_TRUE(component.len >= 0 || component.len == -1); | 94 EXPECT_TRUE(component.len >= 0 || component.len == -1); |
95 | 95 |
96 // Begin should be valid. | 96 // Begin should be valid. |
97 EXPECT_LE(0, component.begin); | 97 EXPECT_LE(0, component.begin); |
98 | 98 |
99 // A NULL reference means the component should be nonexistant. | 99 // A NULL reference means the component should be nonexistent. |
100 if (!reference) | 100 if (!reference) |
101 return component.len == -1; | 101 return component.len == -1; |
102 if (component.len < 0) | 102 if (component.len < 0) |
103 return false; // Reference is not NULL but we don't have anything | 103 return false; // Reference is not NULL but we don't have anything |
104 | 104 |
105 if (strlen(reference) != static_cast<size_t>(component.len)) | 105 if (strlen(reference) != static_cast<size_t>(component.len)) |
106 return false; // Lengths don't match | 106 return false; // Lengths don't match |
107 | 107 |
108 // Now check the actual characters. | 108 // Now check the actual characters. |
109 return strncmp(reference, &input[component.begin], component.len) == 0; | 109 return strncmp(reference, &input[component.begin], component.len) == 0; |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 {"/", NULL, "/"}, | 338 {"/", NULL, "/"}, |
339 {" This is \\interesting// \t", NULL, "This is \\interestin
g// \t"}, | 339 {" This is \\interesting// \t", NULL, "This is \\interestin
g// \t"}, |
340 {"about:", "about", NULL}, | 340 {"about:", "about", NULL}, |
341 {"about:blank", "about", "blank"}, | 341 {"about:blank", "about", "blank"}, |
342 {" about: blank ", "about", " blank "}, | 342 {" about: blank ", "about", " blank "}, |
343 {"javascript :alert(\"He:/l\\l#o?foo\"); ", "javascript ", "alert(\"He:/l\\l#o?f
oo\"); "}, | 343 {"javascript :alert(\"He:/l\\l#o?foo\"); ", "javascript ", "alert(\"He:/l\\l#o?f
oo\"); "}, |
344 }; | 344 }; |
345 | 345 |
346 TEST(URLParser, PathURL) { | 346 TEST(URLParser, PathURL) { |
347 // Declared outside for loop to try to catch cases in init() where we forget | 347 // Declared outside for loop to try to catch cases in init() where we forget |
348 // to reset something that is reset by the construtor. | 348 // to reset something that is reset by the constructor. |
349 Parsed parsed; | 349 Parsed parsed; |
350 for (size_t i = 0; i < arraysize(path_cases); i++) { | 350 for (size_t i = 0; i < arraysize(path_cases); i++) { |
351 const char* url = path_cases[i].input; | 351 const char* url = path_cases[i].input; |
352 ParsePathURL(url, static_cast<int>(strlen(url)), false, &parsed); | 352 ParsePathURL(url, static_cast<int>(strlen(url)), false, &parsed); |
353 | 353 |
354 EXPECT_TRUE(ComponentMatches(url, path_cases[i].scheme, parsed.scheme)) | 354 EXPECT_TRUE(ComponentMatches(url, path_cases[i].scheme, parsed.scheme)) |
355 << i; | 355 << i; |
356 EXPECT_TRUE(ComponentMatches(url, path_cases[i].path, parsed.GetContent())) | 356 EXPECT_TRUE(ComponentMatches(url, path_cases[i].path, parsed.GetContent())) |
357 << i; | 357 << i; |
358 | 358 |
359 // The remaining components are never used for path urls. | 359 // The remaining components are never used for path URLs. |
360 ExpectInvalidComponent(parsed.username); | 360 ExpectInvalidComponent(parsed.username); |
361 ExpectInvalidComponent(parsed.password); | 361 ExpectInvalidComponent(parsed.password); |
362 ExpectInvalidComponent(parsed.host); | 362 ExpectInvalidComponent(parsed.host); |
363 ExpectInvalidComponent(parsed.port); | 363 ExpectInvalidComponent(parsed.port); |
364 } | 364 } |
365 } | 365 } |
366 | 366 |
367 // Various incarnations of file URLs. | 367 // Various incarnations of file URLs. |
368 static URLParseCase file_cases[] = { | 368 static URLParseCase file_cases[] = { |
369 #ifdef WIN32 | 369 #ifdef WIN32 |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 const char* expected_value) { | 530 const char* expected_value) { |
531 Parsed parsed; | 531 Parsed parsed; |
532 ParseStandardURL(url, static_cast<int>(strlen(url)), &parsed); | 532 ParseStandardURL(url, static_cast<int>(strlen(url)), &parsed); |
533 | 533 |
534 Component query = parsed.query; | 534 Component query = parsed.query; |
535 | 535 |
536 for (int i = 1; i <= parameter; i++) { | 536 for (int i = 1; i <= parameter; i++) { |
537 Component key, value; | 537 Component key, value; |
538 if (!ExtractQueryKeyValue(url, &query, &key, &value)) { | 538 if (!ExtractQueryKeyValue(url, &query, &key, &value)) { |
539 if (parameter >= i && !expected_key) | 539 if (parameter >= i && !expected_key) |
540 return true; // Expected nonexistant key, got one. | 540 return true; // Expected nonexistent key, got one. |
541 return false; // Not enough keys. | 541 return false; // Not enough keys. |
542 } | 542 } |
543 | 543 |
544 if (i == parameter) { | 544 if (i == parameter) { |
545 if (!expected_key) | 545 if (!expected_key) |
546 return false; | 546 return false; |
547 | 547 |
548 if (strncmp(&url[key.begin], expected_key, key.len) != 0) | 548 if (strncmp(&url[key.begin], expected_key, key.len) != 0) |
549 return false; | 549 return false; |
550 if (strncmp(&url[value.begin], expected_value, value.len) != 0) | 550 if (strncmp(&url[value.begin], expected_value, value.len) != 0) |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 {"mailto:addr1:addr2 ", "mailto", "addr1:addr2", NULL}, | 606 {"mailto:addr1:addr2 ", "mailto", "addr1:addr2", NULL}, |
607 {"mailto:?to=addr1,addr2", "mailto", NULL, "to=addr1,addr2"}, | 607 {"mailto:?to=addr1,addr2", "mailto", NULL, "to=addr1,addr2"}, |
608 {"mailto:?to=addr1%2C%20addr2", "mailto", NULL, "to=addr1%2C%20add
r2"}, | 608 {"mailto:?to=addr1%2C%20addr2", "mailto", NULL, "to=addr1%2C%20add
r2"}, |
609 {"mailto:addr1?to=addr2", "mailto", "addr1", "to=addr2"}, | 609 {"mailto:addr1?to=addr2", "mailto", "addr1", "to=addr2"}, |
610 {"mailto:?body=#foobar#", "mailto", NULL, "body=#foobar#",}, | 610 {"mailto:?body=#foobar#", "mailto", NULL, "body=#foobar#",}, |
611 {"mailto:#?body=#foobar#", "mailto", "#", "body=#foobar#"}, | 611 {"mailto:#?body=#foobar#", "mailto", "#", "body=#foobar#"}, |
612 }; | 612 }; |
613 | 613 |
614 TEST(URLParser, MailtoUrl) { | 614 TEST(URLParser, MailtoUrl) { |
615 // Declared outside for loop to try to catch cases in init() where we forget | 615 // Declared outside for loop to try to catch cases in init() where we forget |
616 // to reset something that is reset by the construtor. | 616 // to reset something that is reset by the constructor. |
617 Parsed parsed; | 617 Parsed parsed; |
618 for (size_t i = 0; i < arraysize(mailto_cases); ++i) { | 618 for (size_t i = 0; i < arraysize(mailto_cases); ++i) { |
619 const char* url = mailto_cases[i].input; | 619 const char* url = mailto_cases[i].input; |
620 ParseMailtoURL(url, static_cast<int>(strlen(url)), &parsed); | 620 ParseMailtoURL(url, static_cast<int>(strlen(url)), &parsed); |
621 int port = ParsePort(url, parsed.port); | 621 int port = ParsePort(url, parsed.port); |
622 | 622 |
623 EXPECT_TRUE(ComponentMatches(url, mailto_cases[i].scheme, parsed.scheme)); | 623 EXPECT_TRUE(ComponentMatches(url, mailto_cases[i].scheme, parsed.scheme)); |
624 EXPECT_TRUE(ComponentMatches(url, mailto_cases[i].path, parsed.path)); | 624 EXPECT_TRUE(ComponentMatches(url, mailto_cases[i].path, parsed.path)); |
625 EXPECT_TRUE(ComponentMatches(url, mailto_cases[i].query, parsed.query)); | 625 EXPECT_TRUE(ComponentMatches(url, mailto_cases[i].query, parsed.query)); |
626 EXPECT_EQ(PORT_UNSPECIFIED, port); | 626 EXPECT_EQ(PORT_UNSPECIFIED, port); |
627 | 627 |
628 // The remaining components are never used for mailto urls. | 628 // The remaining components are never used for mailto URLs. |
629 ExpectInvalidComponent(parsed.username); | 629 ExpectInvalidComponent(parsed.username); |
630 ExpectInvalidComponent(parsed.password); | 630 ExpectInvalidComponent(parsed.password); |
631 ExpectInvalidComponent(parsed.port); | 631 ExpectInvalidComponent(parsed.port); |
632 ExpectInvalidComponent(parsed.ref); | 632 ExpectInvalidComponent(parsed.ref); |
633 } | 633 } |
634 } | 634 } |
635 | 635 |
636 // Various incarnations of filesystem URLs. | 636 // Various incarnations of filesystem URLs. |
637 static FileSystemURLParseCase filesystem_cases[] = { | 637 static FileSystemURLParseCase filesystem_cases[] = { |
638 // Regular URL with all the parts | 638 // Regular URL with all the parts |
639 {"filesystem:http://user:pass@foo:21/temporary/bar;par?b#c", "http", "user", "p
ass", "foo", 21, "/temporary", "/bar;par", "b", "c"}, | 639 {"filesystem:http://user:pass@foo:21/temporary/bar;par?b#c", "http", "user", "p
ass", "foo", 21, "/temporary", "/bar;par", "b", "c"}, |
640 {"filesystem:https://foo/persistent/bar;par/", "https", NULL, NU
LL, "foo", -1, "/persistent", "/bar;par/", NULL, NULL}, | 640 {"filesystem:https://foo/persistent/bar;par/", "https", NULL, NU
LL, "foo", -1, "/persistent", "/bar;par/", NULL, NULL}, |
641 {"filesystem:file:///persistent/bar;par/", "file", NULL, NU
LL, NULL, -1, "/persistent", "/bar;par/", NULL, NULL}, | 641 {"filesystem:file:///persistent/bar;par/", "file", NULL, NU
LL, NULL, -1, "/persistent", "/bar;par/", NULL, NULL}, |
642 {"filesystem:file:///persistent/bar;par/?query#ref", "file", N
ULL, NULL, NULL, -1, "/persistent", "/bar;par/", "query", "ref"}, | 642 {"filesystem:file:///persistent/bar;par/?query#ref", "file", N
ULL, NULL, NULL, -1, "/persistent", "/bar;par/", "query", "ref"}, |
643 {"filesystem:file:///persistent", "file", NULL, NU
LL, NULL, -1, "/persistent", "", NULL, NULL}, | 643 {"filesystem:file:///persistent", "file", NULL, NU
LL, NULL, -1, "/persistent", "", NULL, NULL}, |
644 }; | 644 }; |
645 | 645 |
646 TEST(URLParser, FileSystemURL) { | 646 TEST(URLParser, FileSystemURL) { |
647 // Declared outside for loop to try to catch cases in init() where we forget | 647 // Declared outside for loop to try to catch cases in init() where we forget |
648 // to reset something that is reset by the construtor. | 648 // to reset something that is reset by the constructor. |
649 Parsed parsed; | 649 Parsed parsed; |
650 for (size_t i = 0; i < arraysize(filesystem_cases); i++) { | 650 for (size_t i = 0; i < arraysize(filesystem_cases); i++) { |
651 const FileSystemURLParseCase* parsecase = &filesystem_cases[i]; | 651 const FileSystemURLParseCase* parsecase = &filesystem_cases[i]; |
652 const char* url = parsecase->input; | 652 const char* url = parsecase->input; |
653 ParseFileSystemURL(url, static_cast<int>(strlen(url)), &parsed); | 653 ParseFileSystemURL(url, static_cast<int>(strlen(url)), &parsed); |
654 | 654 |
655 EXPECT_TRUE(ComponentMatches(url, "filesystem", parsed.scheme)); | 655 EXPECT_TRUE(ComponentMatches(url, "filesystem", parsed.scheme)); |
656 EXPECT_EQ(!parsecase->inner_scheme, !parsed.inner_parsed()); | 656 EXPECT_EQ(!parsecase->inner_scheme, !parsed.inner_parsed()); |
657 // Only check the inner_parsed if there is one. | 657 // Only check the inner_parsed if there is one. |
658 if (parsed.inner_parsed()) { | 658 if (parsed.inner_parsed()) { |
659 EXPECT_TRUE(ComponentMatches(url, parsecase->inner_scheme, | 659 EXPECT_TRUE(ComponentMatches(url, parsecase->inner_scheme, |
660 parsed.inner_parsed()->scheme)); | 660 parsed.inner_parsed()->scheme)); |
661 EXPECT_TRUE(ComponentMatches(url, parsecase->inner_username, | 661 EXPECT_TRUE(ComponentMatches(url, parsecase->inner_username, |
662 parsed.inner_parsed()->username)); | 662 parsed.inner_parsed()->username)); |
663 EXPECT_TRUE(ComponentMatches(url, parsecase->inner_password, | 663 EXPECT_TRUE(ComponentMatches(url, parsecase->inner_password, |
664 parsed.inner_parsed()->password)); | 664 parsed.inner_parsed()->password)); |
665 EXPECT_TRUE(ComponentMatches(url, parsecase->inner_host, | 665 EXPECT_TRUE(ComponentMatches(url, parsecase->inner_host, |
666 parsed.inner_parsed()->host)); | 666 parsed.inner_parsed()->host)); |
667 int port = ParsePort(url, parsed.inner_parsed()->port); | 667 int port = ParsePort(url, parsed.inner_parsed()->port); |
668 EXPECT_EQ(parsecase->inner_port, port); | 668 EXPECT_EQ(parsecase->inner_port, port); |
669 | 669 |
670 // The remaining components are never used for filesystem urls. | 670 // The remaining components are never used for filesystem URLs. |
671 ExpectInvalidComponent(parsed.inner_parsed()->query); | 671 ExpectInvalidComponent(parsed.inner_parsed()->query); |
672 ExpectInvalidComponent(parsed.inner_parsed()->ref); | 672 ExpectInvalidComponent(parsed.inner_parsed()->ref); |
673 } | 673 } |
674 | 674 |
675 EXPECT_TRUE(ComponentMatches(url, parsecase->path, parsed.path)); | 675 EXPECT_TRUE(ComponentMatches(url, parsecase->path, parsed.path)); |
676 EXPECT_TRUE(ComponentMatches(url, parsecase->query, parsed.query)); | 676 EXPECT_TRUE(ComponentMatches(url, parsecase->query, parsed.query)); |
677 EXPECT_TRUE(ComponentMatches(url, parsecase->ref, parsed.ref)); | 677 EXPECT_TRUE(ComponentMatches(url, parsecase->ref, parsed.ref)); |
678 | 678 |
679 // The remaining components are never used for filesystem urls. | 679 // The remaining components are never used for filesystem URLs. |
680 ExpectInvalidComponent(parsed.username); | 680 ExpectInvalidComponent(parsed.username); |
681 ExpectInvalidComponent(parsed.password); | 681 ExpectInvalidComponent(parsed.password); |
682 ExpectInvalidComponent(parsed.host); | 682 ExpectInvalidComponent(parsed.host); |
683 ExpectInvalidComponent(parsed.port); | 683 ExpectInvalidComponent(parsed.port); |
684 } | 684 } |
685 } | 685 } |
686 | 686 |
687 } // namespace | 687 } // namespace |
688 } // namespace url | 688 } // namespace url |
OLD | NEW |