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/url_canon.h" | 10 #include "url/url_canon.h" |
10 #include "url/url_canon_internal.h" | 11 #include "url/url_canon_internal.h" |
11 #include "url/url_canon_stdstring.h" | 12 #include "url/url_canon_stdstring.h" |
12 #include "url/url_parse.h" | |
13 #include "url/url_test_utils.h" | 13 #include "url/url_test_utils.h" |
14 | 14 |
15 namespace url { | 15 namespace url { |
16 | 16 |
17 using test_utils::WStringToUTF16; | 17 using test_utils::WStringToUTF16; |
18 using test_utils::ConvertUTF8ToUTF16; | 18 using test_utils::ConvertUTF8ToUTF16; |
19 using test_utils::ConvertUTF16ToUTF8; | 19 using test_utils::ConvertUTF16ToUTF8; |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
23 struct ComponentCase { | 23 struct ComponentCase { |
24 const char* input; | 24 const char* input; |
25 const char* expected; | 25 const char* expected; |
26 Component expected_component; | 26 Component expected_component; |
27 bool expected_success; | 27 bool expected_success; |
28 }; | 28 }; |
29 | 29 |
30 // ComponentCase but with dual 8-bit/16-bit input. Generally, the unit tests | 30 // ComponentCase but with dual 8-bit/16-bit input. Generally, the unit tests |
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 |