| 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 <errno.h> | 5 #include <errno.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/third_party/mozilla/url_parse.h" | 9 #include "url/third_party/mozilla/url_parse.h" |
| 10 #include "url/url_canon.h" | 10 #include "url/url_canon.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 // treat each input as optional, and will only try processing if non-NULL. | 31 // treat each input as optional, and will only try processing if non-NULL. |
| 32 // The output is always 8-bit. | 32 // The output is always 8-bit. |
| 33 struct DualComponentCase { | 33 struct DualComponentCase { |
| 34 const char* input8; | 34 const char* input8; |
| 35 const wchar_t* input16; | 35 const wchar_t* input16; |
| 36 const char* expected; | 36 const char* expected; |
| 37 Component expected_component; | 37 Component expected_component; |
| 38 bool expected_success; | 38 bool expected_success; |
| 39 }; | 39 }; |
| 40 | 40 |
| 41 // Test cases for CanonicalizeIPAddress(). The inputs are identical to | 41 // Test cases for CanonicalizeIPAddress(). The inputs are identical to |
| 42 // DualComponentCase, but the output has extra CanonHostInfo fields. | 42 // DualComponentCase, but the output has extra CanonHostInfo fields. |
| 43 struct IPAddressCase { | 43 struct IPAddressCase { |
| 44 const char* input8; | 44 const char* input8; |
| 45 const wchar_t* input16; | 45 const wchar_t* input16; |
| 46 const char* expected; | 46 const char* expected; |
| 47 Component expected_component; | 47 Component expected_component; |
| 48 | 48 |
| 49 // CanonHostInfo fields, for verbose output. | 49 // CanonHostInfo fields, for verbose output. |
| 50 CanonHostInfo::Family expected_family; | 50 CanonHostInfo::Family expected_family; |
| 51 int expected_num_ipv4_components; | 51 int expected_num_ipv4_components; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 out_str.clear(); | 120 out_str.clear(); |
| 121 StdStringCanonOutput output(&out_str); | 121 StdStringCanonOutput output(&out_str); |
| 122 AppendUTF8Value(utf_cases[i].input, &output); | 122 AppendUTF8Value(utf_cases[i].input, &output); |
| 123 output.Complete(); | 123 output.Complete(); |
| 124 EXPECT_EQ(utf_cases[i].output, out_str); | 124 EXPECT_EQ(utf_cases[i].output, out_str); |
| 125 } | 125 } |
| 126 } | 126 } |
| 127 | 127 |
| 128 #if defined(GTEST_HAS_DEATH_TEST) | 128 #if defined(GTEST_HAS_DEATH_TEST) |
| 129 // TODO(mattm): Can't run this in debug mode for now, since the DCHECK will | 129 // TODO(mattm): Can't run this in debug mode for now, since the DCHECK will |
| 130 // cause the Chromium stacktrace dialog to appear and hang the test. | 130 // cause the Chromium stack trace dialog to appear and hang the test. |
| 131 // See http://crbug.com/49580. | 131 // See http://crbug.com/49580. |
| 132 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) | 132 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) |
| 133 #define MAYBE_DoAppendUTF8Invalid DoAppendUTF8Invalid | 133 #define MAYBE_DoAppendUTF8Invalid DoAppendUTF8Invalid |
| 134 #else | 134 #else |
| 135 #define MAYBE_DoAppendUTF8Invalid DISABLED_DoAppendUTF8Invalid | 135 #define MAYBE_DoAppendUTF8Invalid DISABLED_DoAppendUTF8Invalid |
| 136 #endif | 136 #endif |
| 137 TEST(URLCanonTest, MAYBE_DoAppendUTF8Invalid) { | 137 TEST(URLCanonTest, MAYBE_DoAppendUTF8Invalid) { |
| 138 std::string out_str; | 138 std::string out_str; |
| 139 StdStringCanonOutput output(&out_str); | 139 StdStringCanonOutput output(&out_str); |
| 140 // Invalid code point (too large). | 140 // Invalid code point (too large). |
| 141 ASSERT_DEBUG_DEATH({ | 141 ASSERT_DEBUG_DEATH({ |
| 142 AppendUTF8Value(0x110000, &output); | 142 AppendUTF8Value(0x110000, &output); |
| 143 output.Complete(); | 143 output.Complete(); |
| 144 EXPECT_EQ("", out_str); | 144 EXPECT_EQ("", out_str); |
| 145 }, ""); | 145 }, ""); |
| 146 } | 146 } |
| 147 #endif // defined(GTEST_HAS_DEATH_TEST) | 147 #endif // defined(GTEST_HAS_DEATH_TEST) |
| 148 | 148 |
| 149 TEST(URLCanonTest, UTF) { | 149 TEST(URLCanonTest, UTF) { |
| 150 // Low-level test that we handle reading, canonicalization, and writing | 150 // Low-level test that we handle reading, canonicalization, and writing |
| 151 // UTF-8/UTF-16 strings properly. | 151 // UTF-8/UTF-16 strings properly. |
| 152 struct UTFCase { | 152 struct UTFCase { |
| 153 const char* input8; | 153 const char* input8; |
| 154 const wchar_t* input16; | 154 const wchar_t* input16; |
| 155 bool expected_success; | 155 bool expected_success; |
| 156 const char* output; | 156 const char* output; |
| 157 } utf_cases[] = { | 157 } utf_cases[] = { |
| 158 // Valid canonical input should get passed through & escaped. | 158 // Valid canonical input should get passed through & escaped. |
| 159 {"\xe4\xbd\xa0\xe5\xa5\xbd", L"\x4f60\x597d", true, "%E4%BD%A0%E5%A5%BD"}, | 159 {"\xe4\xbd\xa0\xe5\xa5\xbd", L"\x4f60\x597d", true, "%E4%BD%A0%E5%A5%BD"}, |
| 160 // Test a characer that takes > 16 bits (U+10300 = old italic letter A) | 160 // Test a character that takes > 16 bits (U+10300 = old italic letter A) |
| 161 {"\xF0\x90\x8C\x80", L"\xd800\xdf00", true, "%F0%90%8C%80"}, | 161 {"\xF0\x90\x8C\x80", L"\xd800\xdf00", true, "%F0%90%8C%80"}, |
| 162 // Non-shortest-form UTF-8 are invalid. The bad char should be replaced | 162 // Non-shortest-form UTF-8 characters are invalid. The bad character |
| 163 // with the invalid character (EF BF DB in UTF-8). | 163 // should be replaced with the invalid character (EF BF DB in UTF-8). |
| 164 {"\xf0\x84\xbd\xa0\xe5\xa5\xbd", NULL, false, "%EF%BF%BD%E5%A5%BD"}, | 164 {"\xf0\x84\xbd\xa0\xe5\xa5\xbd", NULL, false, "%EF%BF%BD%E5%A5%BD"}, |
| 165 // Invalid UTF-8 sequences should be marked as invalid (the first | 165 // Invalid UTF-8 sequences should be marked as invalid (the first |
| 166 // sequence is truncated). | 166 // sequence is truncated). |
| 167 {"\xe4\xa0\xe5\xa5\xbd", L"\xd800\x597d", false, "%EF%BF%BD%E5%A5%BD"}, | 167 {"\xe4\xa0\xe5\xa5\xbd", L"\xd800\x597d", false, "%EF%BF%BD%E5%A5%BD"}, |
| 168 // Character going off the end. | 168 // Character going off the end. |
| 169 {"\xe4\xbd\xa0\xe5\xa5", L"\x4f60\xd800", false, "%E4%BD%A0%EF%BF%BD"}, | 169 {"\xe4\xbd\xa0\xe5\xa5", L"\x4f60\xd800", false, "%E4%BD%A0%EF%BF%BD"}, |
| 170 // ...same with low surrogates with no high surrogate. | 170 // ...same with low surrogates with no high surrogate. |
| 171 {"\xed\xb0\x80", L"\xdc00", false, "%EF%BF%BD"}, | 171 {"\xed\xb0\x80", L"\xdc00", false, "%EF%BF%BD"}, |
| 172 // Test a UTF-8 encoded surrogate value is marked as invalid. | 172 // Test a UTF-8 encoded surrogate value is marked as invalid. |
| 173 // ED A0 80 = U+D800 | 173 // ED A0 80 = U+D800 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 StdStringCanonOutput output1(&out_str); | 252 StdStringCanonOutput output1(&out_str); |
| 253 bool success = CanonicalizeScheme(scheme_cases[i].input, in_comp, &output1, | 253 bool success = CanonicalizeScheme(scheme_cases[i].input, in_comp, &output1, |
| 254 &out_comp); | 254 &out_comp); |
| 255 output1.Complete(); | 255 output1.Complete(); |
| 256 | 256 |
| 257 EXPECT_EQ(scheme_cases[i].expected_success, success); | 257 EXPECT_EQ(scheme_cases[i].expected_success, success); |
| 258 EXPECT_EQ(std::string(scheme_cases[i].expected), out_str); | 258 EXPECT_EQ(std::string(scheme_cases[i].expected), out_str); |
| 259 EXPECT_EQ(scheme_cases[i].expected_component.begin, out_comp.begin); | 259 EXPECT_EQ(scheme_cases[i].expected_component.begin, out_comp.begin); |
| 260 EXPECT_EQ(scheme_cases[i].expected_component.len, out_comp.len); | 260 EXPECT_EQ(scheme_cases[i].expected_component.len, out_comp.len); |
| 261 | 261 |
| 262 // Now try the wide version | 262 // Now try the wide version. |
| 263 out_str.clear(); | 263 out_str.clear(); |
| 264 StdStringCanonOutput output2(&out_str); | 264 StdStringCanonOutput output2(&out_str); |
| 265 | 265 |
| 266 base::string16 wide_input(ConvertUTF8ToUTF16(scheme_cases[i].input)); | 266 base::string16 wide_input(ConvertUTF8ToUTF16(scheme_cases[i].input)); |
| 267 in_comp.len = static_cast<int>(wide_input.length()); | 267 in_comp.len = static_cast<int>(wide_input.length()); |
| 268 success = CanonicalizeScheme(wide_input.c_str(), in_comp, &output2, | 268 success = CanonicalizeScheme(wide_input.c_str(), in_comp, &output2, |
| 269 &out_comp); | 269 &out_comp); |
| 270 output2.Complete(); | 270 output2.Complete(); |
| 271 | 271 |
| 272 EXPECT_EQ(scheme_cases[i].expected_success, success); | 272 EXPECT_EQ(scheme_cases[i].expected_success, success); |
| 273 EXPECT_EQ(std::string(scheme_cases[i].expected), out_str); | 273 EXPECT_EQ(std::string(scheme_cases[i].expected), out_str); |
| 274 EXPECT_EQ(scheme_cases[i].expected_component.begin, out_comp.begin); | 274 EXPECT_EQ(scheme_cases[i].expected_component.begin, out_comp.begin); |
| 275 EXPECT_EQ(scheme_cases[i].expected_component.len, out_comp.len); | 275 EXPECT_EQ(scheme_cases[i].expected_component.len, out_comp.len); |
| 276 } | 276 } |
| 277 | 277 |
| 278 // Test the case where the scheme is declared nonexistant, it should be | 278 // Test the case where the scheme is declared nonexistent, it should be |
| 279 // converted into an empty scheme. | 279 // converted into an empty scheme. |
| 280 Component out_comp; | 280 Component out_comp; |
| 281 out_str.clear(); | 281 out_str.clear(); |
| 282 StdStringCanonOutput output(&out_str); | 282 StdStringCanonOutput output(&out_str); |
| 283 | 283 |
| 284 EXPECT_TRUE(CanonicalizeScheme("", Component(0, -1), &output, &out_comp)); | 284 EXPECT_TRUE(CanonicalizeScheme("", Component(0, -1), &output, &out_comp)); |
| 285 output.Complete(); | 285 output.Complete(); |
| 286 | 286 |
| 287 EXPECT_EQ(std::string(":"), out_str); | 287 EXPECT_EQ(std::string(":"), out_str); |
| 288 EXPECT_EQ(0, out_comp.begin); | 288 EXPECT_EQ(0, out_comp.begin); |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 631 // Repeat the previous tests, minus 1, to verify boundaries. | 631 // Repeat the previous tests, minus 1, to verify boundaries. |
| 632 {"0xFF.0", L"0xFF.0", "255.0.0.0", Component(0, 9), CanonHostInfo::IPV4, 2,
"FF000000"}, | 632 {"0xFF.0", L"0xFF.0", "255.0.0.0", Component(0, 9), CanonHostInfo::IPV4, 2,
"FF000000"}, |
| 633 {"0xFF.0.0", L"0xFF.0.0", "255.0.0.0", Component(0, 9), CanonHostInfo::IPV4,
3, "FF000000"}, | 633 {"0xFF.0.0", L"0xFF.0.0", "255.0.0.0", Component(0, 9), CanonHostInfo::IPV4,
3, "FF000000"}, |
| 634 {"0xFF.0.0.0", L"0xFF.0.0.0", "255.0.0.0", Component(0, 9), CanonHostInfo::I
PV4, 4, "FF000000"}, | 634 {"0xFF.0.0.0", L"0xFF.0.0.0", "255.0.0.0", Component(0, 9), CanonHostInfo::I
PV4, 4, "FF000000"}, |
| 635 {"0.0xFF.0.0", L"0.0xFF.0.0", "0.255.0.0", Component(0, 9), CanonHostInfo::I
PV4, 4, "00FF0000"}, | 635 {"0.0xFF.0.0", L"0.0xFF.0.0", "0.255.0.0", Component(0, 9), CanonHostInfo::I
PV4, 4, "00FF0000"}, |
| 636 {"0.0.0xFF.0", L"0.0.0xFF.0", "0.0.255.0", Component(0, 9), CanonHostInfo::I
PV4, 4, "0000FF00"}, | 636 {"0.0.0xFF.0", L"0.0.0xFF.0", "0.0.255.0", Component(0, 9), CanonHostInfo::I
PV4, 4, "0000FF00"}, |
| 637 {"0.0.0.0xFF", L"0.0.0.0xFF", "0.0.0.255", Component(0, 9), CanonHostInfo::I
PV4, 4, "000000FF"}, | 637 {"0.0.0.0xFF", L"0.0.0.0xFF", "0.0.0.255", Component(0, 9), CanonHostInfo::I
PV4, 4, "000000FF"}, |
| 638 {"0.0.0xFFFF", L"0.0.0xFFFF", "0.0.255.255", Component(0, 11), CanonHostInfo
::IPV4, 3, "0000FFFF"}, | 638 {"0.0.0xFFFF", L"0.0.0xFFFF", "0.0.255.255", Component(0, 11), CanonHostInfo
::IPV4, 3, "0000FFFF"}, |
| 639 {"0.0xFFFFFF", L"0.0xFFFFFF", "0.255.255.255", Component(0, 13), CanonHostIn
fo::IPV4, 2, "00FFFFFF"}, | 639 {"0.0xFFFFFF", L"0.0xFFFFFF", "0.255.255.255", Component(0, 13), CanonHostIn
fo::IPV4, 2, "00FFFFFF"}, |
| 640 {"0xFFFFFFFF", L"0xFFFFFFFF", "255.255.255.255", Component(0, 15), CanonHost
Info::IPV4, 1, "FFFFFFFF"}, | 640 {"0xFFFFFFFF", L"0xFFFFFFFF", "255.255.255.255", Component(0, 15), CanonHost
Info::IPV4, 1, "FFFFFFFF"}, |
| 641 // Old trunctations tests. They're all "BROKEN" now. | 641 // Old trunctations tests. They're all "BROKEN" now. |
| 642 {"276.256.0xf1a2.077777", L"276.256.0xf1a2.077777", "", Component(), CanonHo
stInfo::BROKEN, -1, ""}, | 642 {"276.256.0xf1a2.077777", L"276.256.0xf1a2.077777", "", Component(), CanonHo
stInfo::BROKEN, -1, ""}, |
| 643 {"192.168.0.257", L"192.168.0.257", "", Component(), CanonHostInfo::BROKEN,
-1, ""}, | 643 {"192.168.0.257", L"192.168.0.257", "", Component(), CanonHostInfo::BROKEN,
-1, ""}, |
| 644 {"192.168.0xa20001", L"192.168.0xa20001", "", Component(), CanonHostInfo::BR
OKEN, -1, ""}, | 644 {"192.168.0xa20001", L"192.168.0xa20001", "", Component(), CanonHostInfo::BR
OKEN, -1, ""}, |
| 645 {"192.015052000001", L"192.015052000001", "", Component(), CanonHostInfo::BR
OKEN, -1, ""}, | 645 {"192.015052000001", L"192.015052000001", "", Component(), CanonHostInfo::BR
OKEN, -1, ""}, |
| 646 {"0X12C0a80001", L"0X12C0a80001", "", Component(), CanonHostInfo::BROKEN, -1
, ""}, | 646 {"0X12C0a80001", L"0X12C0a80001", "", Component(), CanonHostInfo::BROKEN, -1
, ""}, |
| 647 {"276.1.2", L"276.1.2", "", Component(), CanonHostInfo::BROKEN, -1, ""}, | 647 {"276.1.2", L"276.1.2", "", Component(), CanonHostInfo::BROKEN, -1, ""}, |
| 648 // Spaces should be rejected. | 648 // Spaces should be rejected. |
| 649 {"192.168.0.1 hello", L"192.168.0.1 hello", "", Component(), CanonHostInfo::
NEUTRAL, -1, ""}, | 649 {"192.168.0.1 hello", L"192.168.0.1 hello", "", Component(), CanonHostInfo::
NEUTRAL, -1, ""}, |
| 650 // Very large numbers. | 650 // Very large numbers. |
| 651 {"0000000000000300.0x00000000000000fF.00000000000000001", L"0000000000000300
.0x00000000000000fF.00000000000000001", "192.255.0.1", Component(0, 11), CanonHo
stInfo::IPV4, 3, "C0FF0001"}, | 651 {"0000000000000300.0x00000000000000fF.00000000000000001", L"0000000000000300
.0x00000000000000fF.00000000000000001", "192.255.0.1", Component(0, 11), CanonHo
stInfo::IPV4, 3, "C0FF0001"}, |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 | 747 |
| 748 // IPv4 using hex. | 748 // IPv4 using hex. |
| 749 // TODO(eroman): Should this format be disallowed? | 749 // TODO(eroman): Should this format be disallowed? |
| 750 {"[::ffff:0xC0.0Xa8.0x0.0x1]", L"[::ffff:0xC0.0Xa8.0x0.0x1]", "[::ffff:c0a8:
1]", Component(0,15), CanonHostInfo::IPV6, -1, "00000000000000000000FFFFC0A80001
"}, | 750 {"[::ffff:0xC0.0Xa8.0x0.0x1]", L"[::ffff:0xC0.0Xa8.0x0.0x1]", "[::ffff:c0a8:
1]", Component(0,15), CanonHostInfo::IPV6, -1, "00000000000000000000FFFFC0A80001
"}, |
| 751 | 751 |
| 752 // There may be zeros surrounding the "::" contraction. | 752 // There may be zeros surrounding the "::" contraction. |
| 753 {"[0:0::0:0:8]", L"[0:0::0:0:8]", "[::8]", Component(0,5), CanonHostInfo::IP
V6, -1, "00000000000000000000000000000008"}, | 753 {"[0:0::0:0:8]", L"[0:0::0:0:8]", "[::8]", Component(0,5), CanonHostInfo::IP
V6, -1, "00000000000000000000000000000008"}, |
| 754 | 754 |
| 755 {"[2001:db8::1]", L"[2001:db8::1]", "[2001:db8::1]", Component(0,13), CanonH
ostInfo::IPV6, -1, "20010DB8000000000000000000000001"}, | 755 {"[2001:db8::1]", L"[2001:db8::1]", "[2001:db8::1]", Component(0,13), CanonH
ostInfo::IPV6, -1, "20010DB8000000000000000000000001"}, |
| 756 | 756 |
| 757 // Can only have one "::" contraction in an IPv6 string literal. | 757 // Can only have one "::" contraction in an IPv6 string literal. |
| 758 {"[2001::db8::1]", L"[2001::db8::1]", "", Component(), CanonHostInfo::BROKEN
, -1, ""}, | 758 {"[2001::db8::1]", L"[2001::db8::1]", "", Component(), CanonHostInfo::BROKEN
, -1, ""}, |
| 759 // No more than 2 consecutive ':'s. | 759 // No more than 2 consecutive ':'s. |
| 760 {"[2001:db8:::1]", L"[2001:db8:::1]", "", Component(), CanonHostInfo::BROKEN
, -1, ""}, | 760 {"[2001:db8:::1]", L"[2001:db8:::1]", "", Component(), CanonHostInfo::BROKEN
, -1, ""}, |
| 761 {"[:::]", L"[:::]", "", Component(), CanonHostInfo::BROKEN, -1, ""}, | 761 {"[:::]", L"[:::]", "", Component(), CanonHostInfo::BROKEN, -1, ""}, |
| 762 // Non-IP addresses due to invalid characters. | 762 // Non-IP addresses due to invalid characters. |
| 763 {"[2001::.com]", L"[2001::.com]", "", Component(), CanonHostInfo::BROKEN, -1
, ""}, | 763 {"[2001::.com]", L"[2001::.com]", "", Component(), CanonHostInfo::BROKEN, -1
, ""}, |
| 764 // If there are not enough components, the last one should fill them out. | 764 // If there are not enough components, the last one should fill them out. |
| 765 // ... omitted at this time ... | 765 // ... omitted at this time ... |
| 766 // Too many components means not an IP address. Similarly with too few if
using IPv4 compat or mapped addresses. | 766 // Too many components means not an IP address. Similarly, with too few |
| 767 // if using IPv4 compat or mapped addresses. |
| 767 {"[::192.168.0.0.1]", L"[::192.168.0.0.1]", "", Component(), CanonHostInfo::
BROKEN, -1, ""}, | 768 {"[::192.168.0.0.1]", L"[::192.168.0.0.1]", "", Component(), CanonHostInfo::
BROKEN, -1, ""}, |
| 768 {"[::ffff:192.168.0.0.1]", L"[::ffff:192.168.0.0.1]", "", Component(), Canon
HostInfo::BROKEN, -1, ""}, | 769 {"[::ffff:192.168.0.0.1]", L"[::ffff:192.168.0.0.1]", "", Component(), Canon
HostInfo::BROKEN, -1, ""}, |
| 769 {"[1:2:3:4:5:6:7:8:9]", L"[1:2:3:4:5:6:7:8:9]", "", Component(), CanonHostIn
fo::BROKEN, -1, ""}, | 770 {"[1:2:3:4:5:6:7:8:9]", L"[1:2:3:4:5:6:7:8:9]", "", Component(), CanonHostIn
fo::BROKEN, -1, ""}, |
| 770 // Too many bits (even though 8 comonents, the last one holds 32 bits). | 771 // Too many bits (even though 8 comonents, the last one holds 32 bits). |
| 771 {"[0:0:0:0:0:0:0:192.168.0.1]", L"[0:0:0:0:0:0:0:192.168.0.1]", "", Componen
t(), CanonHostInfo::BROKEN, -1, ""}, | 772 {"[0:0:0:0:0:0:0:192.168.0.1]", L"[0:0:0:0:0:0:0:192.168.0.1]", "", Componen
t(), CanonHostInfo::BROKEN, -1, ""}, |
| 772 | 773 |
| 773 // Too many bits specified -- the contraction would have to be zero-length | 774 // Too many bits specified -- the contraction would have to be zero-length |
| 774 // to not exceed 128 bits. | 775 // to not exceed 128 bits. |
| 775 {"[1:2:3:4:5:6::192.168.0.1]", L"[1:2:3:4:5:6::192.168.0.1]", "", Component(
), CanonHostInfo::BROKEN, -1, ""}, | 776 {"[1:2:3:4:5:6::192.168.0.1]", L"[1:2:3:4:5:6::192.168.0.1]", "", Component(
), CanonHostInfo::BROKEN, -1, ""}, |
| 776 | 777 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 880 } user_info_cases[] = { | 881 } user_info_cases[] = { |
| 881 {"http://user:pass@host.com/", "user:pass@", Component(0, 4), Component(5, 4
), true}, | 882 {"http://user:pass@host.com/", "user:pass@", Component(0, 4), Component(5, 4
), true}, |
| 882 {"http://@host.com/", "", Component(0, -1), Component(0, -1), true}, | 883 {"http://@host.com/", "", Component(0, -1), Component(0, -1), true}, |
| 883 {"http://:@host.com/", "", Component(0, -1), Component(0, -1), true}, | 884 {"http://:@host.com/", "", Component(0, -1), Component(0, -1), true}, |
| 884 {"http://foo:@host.com/", "foo@", Component(0, 3), Component(0, -1), true}, | 885 {"http://foo:@host.com/", "foo@", Component(0, 3), Component(0, -1), true}, |
| 885 {"http://:foo@host.com/", ":foo@", Component(0, 0), Component(1, 3), true}, | 886 {"http://:foo@host.com/", ":foo@", Component(0, 0), Component(1, 3), true}, |
| 886 {"http://^ :$\t@host.com/", "%5E%20:$%09@", Component(0, 6), Component(7, 4)
, true}, | 887 {"http://^ :$\t@host.com/", "%5E%20:$%09@", Component(0, 6), Component(7, 4)
, true}, |
| 887 {"http://user:pass@/", "user:pass@", Component(0, 4), Component(5, 4), true}
, | 888 {"http://user:pass@/", "user:pass@", Component(0, 4), Component(5, 4), true}
, |
| 888 {"http://%2540:bar@domain.com/", "%2540:bar@", Component(0, 5), Component(6,
3), true }, | 889 {"http://%2540:bar@domain.com/", "%2540:bar@", Component(0, 5), Component(6,
3), true }, |
| 889 | 890 |
| 890 // IE7 compatability: old versions allowed backslashes in usernames, but | 891 // IE7 compatibility: old versions allowed backslashes in usernames, but |
| 891 // IE7 does not. We disallow it as well. | 892 // IE7 does not. We disallow it as well. |
| 892 {"ftp://me\\mydomain:pass@foo.com/", "", Component(0, -1), Component(0, -1),
true}, | 893 {"ftp://me\\mydomain:pass@foo.com/", "", Component(0, -1), Component(0, -1),
true}, |
| 893 }; | 894 }; |
| 894 | 895 |
| 895 for (size_t i = 0; i < arraysize(user_info_cases); i++) { | 896 for (size_t i = 0; i < arraysize(user_info_cases); i++) { |
| 896 int url_len = static_cast<int>(strlen(user_info_cases[i].input)); | 897 int url_len = static_cast<int>(strlen(user_info_cases[i].input)); |
| 897 Parsed parsed; | 898 Parsed parsed; |
| 898 ParseStandardURL(user_info_cases[i].input, url_len, &parsed); | 899 ParseStandardURL(user_info_cases[i].input, url_len, &parsed); |
| 899 Component out_user, out_pass; | 900 Component out_user, out_pass; |
| 900 std::string out_str; | 901 std::string out_str; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 936 EXPECT_EQ(user_info_cases[i].expected_password.begin, out_pass.begin); | 937 EXPECT_EQ(user_info_cases[i].expected_password.begin, out_pass.begin); |
| 937 EXPECT_EQ(user_info_cases[i].expected_password.len, out_pass.len); | 938 EXPECT_EQ(user_info_cases[i].expected_password.len, out_pass.len); |
| 938 } | 939 } |
| 939 } | 940 } |
| 940 | 941 |
| 941 TEST(URLCanonTest, Port) { | 942 TEST(URLCanonTest, Port) { |
| 942 // We only need to test that the number gets properly put into the output | 943 // We only need to test that the number gets properly put into the output |
| 943 // buffer. The parser unit tests will test scanning the number correctly. | 944 // buffer. The parser unit tests will test scanning the number correctly. |
| 944 // | 945 // |
| 945 // Note that the CanonicalizePort will always prepend a colon to the output | 946 // Note that the CanonicalizePort will always prepend a colon to the output |
| 946 // to separate it from the colon that it assumes preceeds it. | 947 // to separate it from the colon that it assumes precedes it. |
| 947 struct PortCase { | 948 struct PortCase { |
| 948 const char* input; | 949 const char* input; |
| 949 int default_port; | 950 int default_port; |
| 950 const char* expected; | 951 const char* expected; |
| 951 Component expected_component; | 952 Component expected_component; |
| 952 bool expected_success; | 953 bool expected_success; |
| 953 } port_cases[] = { | 954 } port_cases[] = { |
| 954 // Invalid input should be copied w/ failure. | 955 // Invalid input should be copied w/ failure. |
| 955 {"as df", 80, ":as%20df", Component(1, 7), false}, | 956 {"as df", 80, ":as%20df", Component(1, 7), false}, |
| 956 {"-2", 80, ":-2", Component(1, 2), false}, | 957 {"-2", 80, ":-2", Component(1, 2), false}, |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1322 // The codepath here is the same as for regular canonicalization, so we just | 1323 // The codepath here is the same as for regular canonicalization, so we just |
| 1323 // need to test that things are replaced or not correctly. | 1324 // need to test that things are replaced or not correctly. |
| 1324 TEST(URLCanonTest, ReplaceStandardURL) { | 1325 TEST(URLCanonTest, ReplaceStandardURL) { |
| 1325 ReplaceCase replace_cases[] = { | 1326 ReplaceCase replace_cases[] = { |
| 1326 // Common case of truncating the path. | 1327 // Common case of truncating the path. |
| 1327 {"http://www.google.com/foo?bar=baz#ref", NULL, NULL, NULL, NULL, NULL, "/",
kDeleteComp, kDeleteComp, "http://www.google.com/"}, | 1328 {"http://www.google.com/foo?bar=baz#ref", NULL, NULL, NULL, NULL, NULL, "/",
kDeleteComp, kDeleteComp, "http://www.google.com/"}, |
| 1328 // Replace everything | 1329 // Replace everything |
| 1329 {"http://a:b@google.com:22/foo;bar?baz@cat", "https", "me", "pw", "host.com"
, "99", "/path", "query", "ref", "https://me:pw@host.com:99/path?query#ref"}, | 1330 {"http://a:b@google.com:22/foo;bar?baz@cat", "https", "me", "pw", "host.com"
, "99", "/path", "query", "ref", "https://me:pw@host.com:99/path?query#ref"}, |
| 1330 // Replace nothing | 1331 // Replace nothing |
| 1331 {"http://a:b@google.com:22/foo?baz@cat", NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, "http://a:b@google.com:22/foo?baz@cat"}, | 1332 {"http://a:b@google.com:22/foo?baz@cat", NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, "http://a:b@google.com:22/foo?baz@cat"}, |
| 1332 // Replace scheme with filesystem. The result is garbage, but you asked | 1333 // Replace scheme with filesystem. The result is garbage, but you asked |
| 1333 // for it. | 1334 // for it. |
| 1334 {"http://a:b@google.com:22/foo?baz@cat", "filesystem", NULL, NULL, NULL, NUL
L, NULL, NULL, NULL, "filesystem://a:b@google.com:22/foo?baz@cat"}, | 1335 {"http://a:b@google.com:22/foo?baz@cat", "filesystem", NULL, NULL, NULL, NUL
L, NULL, NULL, NULL, "filesystem://a:b@google.com:22/foo?baz@cat"}, |
| 1335 }; | 1336 }; |
| 1336 | 1337 |
| 1337 for (size_t i = 0; i < arraysize(replace_cases); i++) { | 1338 for (size_t i = 0; i < arraysize(replace_cases); i++) { |
| 1338 const ReplaceCase& cur = replace_cases[i]; | 1339 const ReplaceCase& cur = replace_cases[i]; |
| 1339 int base_len = static_cast<int>(strlen(cur.base)); | 1340 int base_len = static_cast<int>(strlen(cur.base)); |
| 1340 Parsed parsed; | 1341 Parsed parsed; |
| 1341 ParseStandardURL(cur.base, base_len, &parsed); | 1342 ParseStandardURL(cur.base, base_len, &parsed); |
| 1342 | 1343 |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1587 Component expected_host; | 1588 Component expected_host; |
| 1588 Component expected_path; | 1589 Component expected_path; |
| 1589 } cases[] = { | 1590 } cases[] = { |
| 1590 #ifdef _WIN32 | 1591 #ifdef _WIN32 |
| 1591 // Windows-style paths | 1592 // Windows-style paths |
| 1592 {"file:c:\\foo\\bar.html", "file:///C:/foo/bar.html", true, Component(), Com
ponent(7, 16)}, | 1593 {"file:c:\\foo\\bar.html", "file:///C:/foo/bar.html", true, Component(), Com
ponent(7, 16)}, |
| 1593 {" File:c|////foo\\bar.html", "file:///C:////foo/bar.html", true, Component
(), Component(7, 19)}, | 1594 {" File:c|////foo\\bar.html", "file:///C:////foo/bar.html", true, Component
(), Component(7, 19)}, |
| 1594 {"file:", "file:///", true, Component(), Component(7, 1)}, | 1595 {"file:", "file:///", true, Component(), Component(7, 1)}, |
| 1595 {"file:UNChost/path", "file://unchost/path", true, Component(7, 7), Componen
t(14, 5)}, | 1596 {"file:UNChost/path", "file://unchost/path", true, Component(7, 7), Componen
t(14, 5)}, |
| 1596 // CanonicalizeFileURL supports absolute Windows style paths for IE | 1597 // CanonicalizeFileURL supports absolute Windows style paths for IE |
| 1597 // compatability. Note that the caller must decide that this is a file | 1598 // compatibility. Note that the caller must decide that this is a file |
| 1598 // URL itself so it can call the file canonicalizer. This is usually | 1599 // URL itself so it can call the file canonicalizer. This is usually |
| 1599 // done automatically as part of relative URL resolving. | 1600 // done automatically as part of relative URL resolving. |
| 1600 {"c:\\foo\\bar", "file:///C:/foo/bar", true, Component(), Component(7, 11)}, | 1601 {"c:\\foo\\bar", "file:///C:/foo/bar", true, Component(), Component(7, 11)}, |
| 1601 {"C|/foo/bar", "file:///C:/foo/bar", true, Component(), Component(7, 11)}, | 1602 {"C|/foo/bar", "file:///C:/foo/bar", true, Component(), Component(7, 11)}, |
| 1602 {"/C|\\foo\\bar", "file:///C:/foo/bar", true, Component(), Component(7, 11)}
, | 1603 {"/C|\\foo\\bar", "file:///C:/foo/bar", true, Component(), Component(7, 11)}
, |
| 1603 {"//C|/foo/bar", "file:///C:/foo/bar", true, Component(), Component(7, 11)}, | 1604 {"//C|/foo/bar", "file:///C:/foo/bar", true, Component(), Component(7, 11)}, |
| 1604 {"//server/file", "file://server/file", true, Component(7, 6), Component(13,
5)}, | 1605 {"//server/file", "file://server/file", true, Component(7, 6), Component(13,
5)}, |
| 1605 {"\\\\server\\file", "file://server/file", true, Component(7, 6), Component(
13, 5)}, | 1606 {"\\\\server\\file", "file://server/file", true, Component(7, 6), Component(
13, 5)}, |
| 1606 {"/\\server/file", "file://server/file", true, Component(7, 6), Component(13
, 5)}, | 1607 {"/\\server/file", "file://server/file", true, Component(7, 6), Component(13
, 5)}, |
| 1607 // We should preserve the number of slashes after the colon for IE | 1608 // We should preserve the number of slashes after the colon for IE |
| 1608 // compatability, except when there is none, in which case we should | 1609 // compatibility, except when there is none, in which case we should |
| 1609 // add one. | 1610 // add one. |
| 1610 {"file:c:foo/bar.html", "file:///C:/foo/bar.html", true, Component(), Compon
ent(7, 16)}, | 1611 {"file:c:foo/bar.html", "file:///C:/foo/bar.html", true, Component(), Compon
ent(7, 16)}, |
| 1611 {"file:/\\/\\C:\\\\//foo\\bar.html", "file:///C:////foo/bar.html", true, Com
ponent(), Component(7, 19)}, | 1612 {"file:/\\/\\C:\\\\//foo\\bar.html", "file:///C:////foo/bar.html", true, Com
ponent(), Component(7, 19)}, |
| 1612 // Three slashes should be non-UNC, even if there is no drive spec (IE | 1613 // Three slashes should be non-UNC, even if there is no drive spec (IE |
| 1613 // does this, which makes the resulting request invalid). | 1614 // does this, which makes the resulting request invalid). |
| 1614 {"file:///foo/bar.txt", "file:///foo/bar.txt", true, Component(), Component(
7, 12)}, | 1615 {"file:///foo/bar.txt", "file:///foo/bar.txt", true, Component(), Component(
7, 12)}, |
| 1615 // TODO(brettw) we should probably fail for invalid host names, which | 1616 // TODO(brettw) we should probably fail for invalid host names, which |
| 1616 // would change the expected result on this test. We also currently allow | 1617 // would change the expected result on this test. We also currently allow |
| 1617 // colon even though it's probably invalid, because its currently the | 1618 // colon even though it's probably invalid, because its currently the |
| 1618 // "natural" result of the way the canonicalizer is written. There doesn't | 1619 // "natural" result of the way the canonicalizer is written. There doesn't |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1800 | 1801 |
| 1801 EXPECT_EQ(cases[i].expected_query.begin, out_parsed.query.begin); | 1802 EXPECT_EQ(cases[i].expected_query.begin, out_parsed.query.begin); |
| 1802 EXPECT_EQ(cases[i].expected_query.len, out_parsed.query.len); | 1803 EXPECT_EQ(cases[i].expected_query.len, out_parsed.query.len); |
| 1803 } | 1804 } |
| 1804 } | 1805 } |
| 1805 | 1806 |
| 1806 #ifndef WIN32 | 1807 #ifndef WIN32 |
| 1807 | 1808 |
| 1808 TEST(URLCanonTest, _itoa_s) { | 1809 TEST(URLCanonTest, _itoa_s) { |
| 1809 // We fill the buffer with 0xff to ensure that it's getting properly | 1810 // We fill the buffer with 0xff to ensure that it's getting properly |
| 1810 // null-terminated. We also allocate one byte more than what we tell | 1811 // null-terminated. We also allocate one byte more than what we tell |
| 1811 // _itoa_s about, and ensure that the extra byte is untouched. | 1812 // _itoa_s about, and ensure that the extra byte is untouched. |
| 1812 char buf[6]; | 1813 char buf[6]; |
| 1813 memset(buf, 0xff, sizeof(buf)); | 1814 memset(buf, 0xff, sizeof(buf)); |
| 1814 EXPECT_EQ(0, _itoa_s(12, buf, sizeof(buf) - 1, 10)); | 1815 EXPECT_EQ(0, _itoa_s(12, buf, sizeof(buf) - 1, 10)); |
| 1815 EXPECT_STREQ("12", buf); | 1816 EXPECT_STREQ("12", buf); |
| 1816 EXPECT_EQ('\xFF', buf[3]); | 1817 EXPECT_EQ('\xFF', buf[3]); |
| 1817 | 1818 |
| 1818 // Test the edge cases - exactly the buffer size and one over | 1819 // Test the edge cases - exactly the buffer size and one over |
| 1819 memset(buf, 0xff, sizeof(buf)); | 1820 memset(buf, 0xff, sizeof(buf)); |
| 1820 EXPECT_EQ(0, _itoa_s(1234, buf, sizeof(buf) - 1, 10)); | 1821 EXPECT_EQ(0, _itoa_s(1234, buf, sizeof(buf) - 1, 10)); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1839 | 1840 |
| 1840 // Test that radix 16 is supported. | 1841 // Test that radix 16 is supported. |
| 1841 memset(buf, 0xff, sizeof(buf)); | 1842 memset(buf, 0xff, sizeof(buf)); |
| 1842 EXPECT_EQ(0, _itoa_s(1234, buf, sizeof(buf) - 1, 16)); | 1843 EXPECT_EQ(0, _itoa_s(1234, buf, sizeof(buf) - 1, 16)); |
| 1843 EXPECT_STREQ("4d2", buf); | 1844 EXPECT_STREQ("4d2", buf); |
| 1844 EXPECT_EQ('\xFF', buf[5]); | 1845 EXPECT_EQ('\xFF', buf[5]); |
| 1845 } | 1846 } |
| 1846 | 1847 |
| 1847 TEST(URLCanonTest, _itow_s) { | 1848 TEST(URLCanonTest, _itow_s) { |
| 1848 // We fill the buffer with 0xff to ensure that it's getting properly | 1849 // We fill the buffer with 0xff to ensure that it's getting properly |
| 1849 // null-terminated. We also allocate one byte more than what we tell | 1850 // null-terminated. We also allocate one byte more than what we tell |
| 1850 // _itoa_s about, and ensure that the extra byte is untouched. | 1851 // _itoa_s about, and ensure that the extra byte is untouched. |
| 1851 base::char16 buf[6]; | 1852 base::char16 buf[6]; |
| 1852 const char fill_mem = 0xff; | 1853 const char fill_mem = 0xff; |
| 1853 const base::char16 fill_char = 0xffff; | 1854 const base::char16 fill_char = 0xffff; |
| 1854 memset(buf, fill_mem, sizeof(buf)); | 1855 memset(buf, fill_mem, sizeof(buf)); |
| 1855 EXPECT_EQ(0, _itow_s(12, buf, sizeof(buf) / 2 - 1, 10)); | 1856 EXPECT_EQ(0, _itow_s(12, buf, sizeof(buf) / 2 - 1, 10)); |
| 1856 EXPECT_EQ(WStringToUTF16(L"12"), base::string16(buf)); | 1857 EXPECT_EQ(WStringToUTF16(L"12"), base::string16(buf)); |
| 1857 EXPECT_EQ(fill_char, buf[3]); | 1858 EXPECT_EQ(fill_char, buf[3]); |
| 1858 | 1859 |
| 1859 // Test the edge cases - exactly the buffer size and one over | 1860 // Test the edge cases - exactly the buffer size and one over |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2015 // Even on Windows, we don't allow relative drive specs when the base | 2016 // Even on Windows, we don't allow relative drive specs when the base |
| 2016 // is not file. | 2017 // is not file. |
| 2017 {"http://host/a", true, false, "/c:\\foo", true, true, true, "http://host/c:
/foo"}, | 2018 {"http://host/a", true, false, "/c:\\foo", true, true, true, "http://host/c:
/foo"}, |
| 2018 {"http://host/a", true, false, "//c:\\foo", true, true, true, "http://c/foo"
}, | 2019 {"http://host/a", true, false, "//c:\\foo", true, true, true, "http://c/foo"
}, |
| 2019 // Ensure that ports aren't allowed for hosts relative to a file url. | 2020 // Ensure that ports aren't allowed for hosts relative to a file url. |
| 2020 // Although the result string shows a host:port portion, the call to | 2021 // Although the result string shows a host:port portion, the call to |
| 2021 // resolve the relative URL returns false, indicating parse failure, | 2022 // resolve the relative URL returns false, indicating parse failure, |
| 2022 // which is what is required. | 2023 // which is what is required. |
| 2023 {"file:///foo.txt", true, true, "//host:80/bar.txt", true, true, false, "fil
e://host:80/bar.txt"}, | 2024 {"file:///foo.txt", true, true, "//host:80/bar.txt", true, true, false, "fil
e://host:80/bar.txt"}, |
| 2024 // Filesystem URL tests; filesystem URLs are only valid and relative if | 2025 // Filesystem URL tests; filesystem URLs are only valid and relative if |
| 2025 // they have no scheme, e.g. "./index.html". There's no valid equivalent | 2026 // they have no scheme, e.g. "./index.html". There's no valid equivalent |
| 2026 // to http:index.html. | 2027 // to http:index.html. |
| 2027 {"filesystem:http://host/t/path", true, false, "filesystem:http://host/t/pat
h2", true, false, false, NULL}, | 2028 {"filesystem:http://host/t/path", true, false, "filesystem:http://host/t/pat
h2", true, false, false, NULL}, |
| 2028 {"filesystem:http://host/t/path", true, false, "filesystem:https://host/t/pa
th2", true, false, false, NULL}, | 2029 {"filesystem:http://host/t/path", true, false, "filesystem:https://host/t/pa
th2", true, false, false, NULL}, |
| 2029 {"filesystem:http://host/t/path", true, false, "http://host/t/path2", true,
false, false, NULL}, | 2030 {"filesystem:http://host/t/path", true, false, "http://host/t/path2", true,
false, false, NULL}, |
| 2030 {"http://host/t/path", true, false, "filesystem:http://host/t/path2", true,
false, false, NULL}, | 2031 {"http://host/t/path", true, false, "filesystem:http://host/t/path2", true,
false, false, NULL}, |
| 2031 {"filesystem:http://host/t/path", true, false, "./path2", true, true, true,
"filesystem:http://host/t/path2"}, | 2032 {"filesystem:http://host/t/path", true, false, "./path2", true, true, true,
"filesystem:http://host/t/path2"}, |
| 2032 {"filesystem:http://host/t/path/", true, false, "path2", true, true, true, "
filesystem:http://host/t/path/path2"}, | 2033 {"filesystem:http://host/t/path/", true, false, "path2", true, true, true, "
filesystem:http://host/t/path/path2"}, |
| 2033 {"filesystem:http://host/t/path", true, false, "filesystem:http:path2", true
, false, false, NULL}, | 2034 {"filesystem:http://host/t/path", true, false, "filesystem:http:path2", true
, false, false, NULL}, |
| 2034 // Absolute URLs are still not relative to a non-standard base URL. | 2035 // Absolute URLs are still not relative to a non-standard base URL. |
| 2035 {"about:blank", false, false, "http://X/A", true, false, true, ""}, | 2036 {"about:blank", false, false, "http://X/A", true, false, true, ""}, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2083 } else if (cur_case.is_base_hier) { | 2084 } else if (cur_case.is_base_hier) { |
| 2084 ParseStandardURL(resolved.c_str(), resolved_len, &ref_parsed); | 2085 ParseStandardURL(resolved.c_str(), resolved_len, &ref_parsed); |
| 2085 } else { | 2086 } else { |
| 2086 ParsePathURL(resolved.c_str(), resolved_len, false, &ref_parsed); | 2087 ParsePathURL(resolved.c_str(), resolved_len, false, &ref_parsed); |
| 2087 } | 2088 } |
| 2088 EXPECT_TRUE(ParsedIsEqual(ref_parsed, resolved_parsed)); | 2089 EXPECT_TRUE(ParsedIsEqual(ref_parsed, resolved_parsed)); |
| 2089 } | 2090 } |
| 2090 } | 2091 } |
| 2091 } | 2092 } |
| 2092 | 2093 |
| 2093 // It used to be when we did a replacement with a long buffer of UTF-16 | 2094 // It used to be the case that when we did a replacement with a long buffer of |
| 2094 // characters, we would get invalid data in the URL. This is because the buffer | 2095 // UTF-16 characters, we would get invalid data in the URL. This is because the |
| 2095 // it used to hold the UTF-8 data was resized, while some pointers were still | 2096 // buffer that it used to hold the UTF-8 data was resized, while some pointers |
| 2096 // kept to the old buffer that was removed. | 2097 // were still kept to the old buffer that was removed. |
| 2097 TEST(URLCanonTest, ReplacementOverflow) { | 2098 TEST(URLCanonTest, ReplacementOverflow) { |
| 2098 const char src[] = "file:///C:/foo/bar"; | 2099 const char src[] = "file:///C:/foo/bar"; |
| 2099 int src_len = static_cast<int>(strlen(src)); | 2100 int src_len = static_cast<int>(strlen(src)); |
| 2100 Parsed parsed; | 2101 Parsed parsed; |
| 2101 ParseFileURL(src, src_len, &parsed); | 2102 ParseFileURL(src, src_len, &parsed); |
| 2102 | 2103 |
| 2103 // Override two components, the path with something short, and the query with | 2104 // Override two components, the path with something short, and the query with |
| 2104 // sonething long enough to trigger the bug. | 2105 // something long enough to trigger the bug. |
| 2105 Replacements<base::char16> repl; | 2106 Replacements<base::char16> repl; |
| 2106 base::string16 new_query; | 2107 base::string16 new_query; |
| 2107 for (int i = 0; i < 4800; i++) | 2108 for (int i = 0; i < 4800; i++) |
| 2108 new_query.push_back('a'); | 2109 new_query.push_back('a'); |
| 2109 | 2110 |
| 2110 base::string16 new_path(WStringToUTF16(L"/foo")); | 2111 base::string16 new_path(WStringToUTF16(L"/foo")); |
| 2111 repl.SetPath(new_path.c_str(), Component(0, 4)); | 2112 repl.SetPath(new_path.c_str(), Component(0, 4)); |
| 2112 repl.SetQuery(new_query.c_str(), | 2113 repl.SetQuery(new_query.c_str(), |
| 2113 Component(0, static_cast<int>(new_query.length()))); | 2114 Component(0, static_cast<int>(new_query.length()))); |
| 2114 | 2115 |
| 2115 // Call ReplaceComponents on the string. It doesn't matter if we call it for | 2116 // Call ReplaceComponents on the string. It doesn't matter if we call it for |
| 2116 // standard URLs, file URLs, etc, since they will go to the same replacement | 2117 // standard URLs, file URLs, etc, since they will go to the same replacement |
| 2117 // function that was buggy. | 2118 // function that was buggy. |
| 2118 Parsed repl_parsed; | 2119 Parsed repl_parsed; |
| 2119 std::string repl_str; | 2120 std::string repl_str; |
| 2120 StdStringCanonOutput repl_output(&repl_str); | 2121 StdStringCanonOutput repl_output(&repl_str); |
| 2121 ReplaceFileURL(src, parsed, repl, NULL, &repl_output, &repl_parsed); | 2122 ReplaceFileURL(src, parsed, repl, NULL, &repl_output, &repl_parsed); |
| 2122 repl_output.Complete(); | 2123 repl_output.Complete(); |
| 2123 | 2124 |
| 2124 // Generate the expected string and check. | 2125 // Generate the expected string and check. |
| 2125 std::string expected("file:///foo?"); | 2126 std::string expected("file:///foo?"); |
| 2126 for (size_t i = 0; i < new_query.length(); i++) | 2127 for (size_t i = 0; i < new_query.length(); i++) |
| 2127 expected.push_back('a'); | 2128 expected.push_back('a'); |
| 2128 EXPECT_TRUE(expected == repl_str); | 2129 EXPECT_TRUE(expected == repl_str); |
| 2129 } | 2130 } |
| 2130 | 2131 |
| 2131 } // namespace url | 2132 } // namespace url |
| OLD | NEW |