1/* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31// Basic tests that verify our KURL's interface behaves the same as the 32// original KURL's. 33 34#include "config.h" 35#include "platform/weborigin/KURL.h" 36 37#include "wtf/testing/WTFTestHelpers.h" 38#include "wtf/text/CString.h" 39#include "wtf/text/WTFString.h" 40#include <gtest/gtest.h> 41 42namespace { 43 44struct ComponentCase { 45 const char* url; 46 const char* protocol; 47 const char* host; 48 const int port; 49 const char* user; 50 const char* pass; 51 const char* lastPath; 52 const char* query; 53 const char* ref; 54}; 55 56// Test the cases where we should be the same as WebKit's old KURL. 57TEST(KURLTest, SameGetters) 58{ 59 struct GetterCase { 60 const char* url; 61 const char* protocol; 62 const char* host; 63 int port; 64 const char* user; 65 const char* pass; 66 const char* lastPathComponent; 67 const char* query; 68 const char* ref; 69 bool hasRef; 70 } cases[] = { 71 {"http://www.google.com/foo/blah?bar=baz#ref", "http", "www.google.com", 0, "", 0, "blah", "bar=baz", "ref", true}, 72 {"http://foo.com:1234/foo/bar/", "http", "foo.com", 1234, "", 0, "bar", 0, 0, false}, 73 {"http://www.google.com?#", "http", "www.google.com", 0, "", 0, 0, "", "", true}, 74 {"https://me:pass@google.com:23#foo", "https", "google.com", 23, "me", "pass", 0, 0, "foo", true}, 75 {"javascript:hello!//world", "javascript", "", 0, "", 0, "world", 0, 0, false}, 76 }; 77 78 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) { 79 // UTF-8 80 blink::KURL kurl(blink::ParsedURLString, cases[i].url); 81 82 EXPECT_EQ(cases[i].protocol, kurl.protocol()); 83 EXPECT_EQ(cases[i].host, kurl.host()); 84 EXPECT_EQ(cases[i].port, kurl.port()); 85 EXPECT_EQ(cases[i].user, kurl.user()); 86 EXPECT_EQ(cases[i].pass, kurl.pass()); 87 EXPECT_EQ(cases[i].lastPathComponent, kurl.lastPathComponent()); 88 EXPECT_EQ(cases[i].query, kurl.query()); 89 EXPECT_EQ(cases[i].ref, kurl.fragmentIdentifier()); 90 EXPECT_EQ(cases[i].hasRef, kurl.hasFragmentIdentifier()); 91 92 // UTF-16 93 WTF::String utf16(cases[i].url); 94 kurl = blink::KURL(blink::ParsedURLString, utf16); 95 96 EXPECT_EQ(cases[i].protocol, kurl.protocol()); 97 EXPECT_EQ(cases[i].host, kurl.host()); 98 EXPECT_EQ(cases[i].port, kurl.port()); 99 EXPECT_EQ(cases[i].user, kurl.user()); 100 EXPECT_EQ(cases[i].pass, kurl.pass()); 101 EXPECT_EQ(cases[i].lastPathComponent, kurl.lastPathComponent()); 102 EXPECT_EQ(cases[i].query, kurl.query()); 103 EXPECT_EQ(cases[i].ref, kurl.fragmentIdentifier()); 104 EXPECT_EQ(cases[i].hasRef, kurl.hasFragmentIdentifier()); 105 } 106} 107 108// Test a few cases where we're different just to make sure we give reasonable 109// output. 110TEST(KURLTest, DISABLED_DifferentGetters) 111{ 112 ComponentCase cases[] = { 113 // url protocol host port user pass lastPath query ref 114 115 // Old WebKit allows references and queries in what we call "path" URLs 116 // like javascript, so the path here will only consist of "hello!". 117 {"javascript:hello!?#/\\world", "javascript", "", 0, "", 0, "world", 0, 0}, 118 119 // Old WebKit doesn't handle "parameters" in paths, so will 120 // disagree with us about where the path is for this URL. 121 {"http://a.com/hello;world", "http", "a.com", 0, "", 0, "hello", 0, 0}, 122 123 // WebKit doesn't like UTF-8 or UTF-16 input. 124 {"http://\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xbd\xa0\xe5\xa5\xbd/", "http", "xn--6qqa088eba", 0, "", 0, 0, 0, 0}, 125 126 // WebKit %-escapes non-ASCII characters in reference, but we don't. 127 {"http://www.google.com/foo/blah?bar=baz#\xce\xb1\xce\xb2", "http", "www.google.com", 0, "", 0, "blah", "bar=baz", "\xce\xb1\xce\xb2"}, 128 }; 129 130 for (size_t i = 0; i < arraysize(cases); i++) { 131 blink::KURL kurl(blink::ParsedURLString, cases[i].url); 132 133 EXPECT_EQ(cases[i].protocol, kurl.protocol()); 134 EXPECT_EQ(cases[i].host, kurl.host()); 135 EXPECT_EQ(cases[i].port, kurl.port()); 136 EXPECT_EQ(cases[i].user, kurl.user()); 137 EXPECT_EQ(cases[i].pass, kurl.pass()); 138 EXPECT_EQ(cases[i].lastPath, kurl.lastPathComponent()); 139 EXPECT_EQ(cases[i].query, kurl.query()); 140 // Want to compare UCS-16 refs (or to null). 141 if (cases[i].ref) 142 EXPECT_EQ(WTF::String::fromUTF8(cases[i].ref), kurl.fragmentIdentifier()); 143 else 144 EXPECT_TRUE(kurl.fragmentIdentifier().isNull()); 145 } 146} 147 148// Ensures that both ASCII and UTF-8 canonical URLs are handled properly and we 149// get the correct string object out. 150TEST(KURLTest, DISABLED_UTF8) 151{ 152 const char asciiURL[] = "http://foo/bar#baz"; 153 blink::KURL asciiKURL(blink::ParsedURLString, asciiURL); 154 EXPECT_TRUE(asciiKURL.string() == WTF::String(asciiURL)); 155 156 // When the result is ASCII, we should get an ASCII String. Some 157 // code depends on being able to compare the result of the .string() 158 // getter with another String, and the isASCIIness of the two 159 // strings must match for these functions (like equalIgnoringCase). 160 EXPECT_TRUE(WTF::equalIgnoringCase(asciiKURL, WTF::String(asciiURL))); 161 162 // Reproduce code path in FrameLoader.cpp -- equalIgnoringCase implicitly 163 // expects gkurl.protocol() to have been created as ascii. 164 blink::KURL mailto(blink::ParsedURLString, "mailto:foo@foo.com"); 165 EXPECT_TRUE(WTF::equalIgnoringCase(mailto.protocol(), "mailto")); 166 167 const char utf8URL[] = "http://foo/bar#\xe4\xbd\xa0\xe5\xa5\xbd"; 168 blink::KURL utf8KURL(blink::ParsedURLString, utf8URL); 169 170 EXPECT_TRUE(utf8KURL.string() == WTF::String::fromUTF8(utf8URL)); 171} 172 173TEST(KURLTest, Setters) 174{ 175 // Replace the starting URL with the given components one at a time and 176 // verify that we're always the same as the old KURL. 177 // 178 // Note that old KURL won't canonicalize the default port away, so we 179 // can't set setting the http port to "80" (or even "0"). 180 // 181 // We also can't test clearing the query. 182 struct ExpectedComponentCase { 183 const char* url; 184 185 const char* protocol; 186 const char* expectedProtocol; 187 188 const char* host; 189 const char* expectedHost; 190 191 const int port; 192 const char* expectedPort; 193 194 const char* user; 195 const char* expectedUser; 196 197 const char* pass; 198 const char* expectedPass; 199 200 const char* path; 201 const char* expectedPath; 202 203 const char* query; 204 const char* expectedQuery; 205 } cases[] = { 206 { 207 "http://www.google.com/", 208 // protocol 209 "https", "https://www.google.com/", 210 // host 211 "news.google.com", "https://news.google.com/", 212 // port 213 8888, "https://news.google.com:8888/", 214 // user 215 "me", "https://me@news.google.com:8888/", 216 // pass 217 "pass", "https://me:pass@news.google.com:8888/", 218 // path 219 "/foo", "https://me:pass@news.google.com:8888/foo", 220 // query 221 "?q=asdf", "https://me:pass@news.google.com:8888/foo?q=asdf" 222 }, { 223 "https://me:pass@google.com:88/a?f#b", 224 // protocol 225 "http", "http://me:pass@google.com:88/a?f#b", 226 // host 227 "goo.com", "http://me:pass@goo.com:88/a?f#b", 228 // port 229 92, "http://me:pass@goo.com:92/a?f#b", 230 // user 231 "", "http://:pass@goo.com:92/a?f#b", 232 // pass 233 "", "http://goo.com:92/a?f#b", 234 // path 235 "/", "http://goo.com:92/?f#b", 236 // query 237 0, "http://goo.com:92/#b" 238 }, 239 }; 240 241 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) { 242 blink::KURL kurl(blink::ParsedURLString, cases[i].url); 243 244 kurl.setProtocol(cases[i].protocol); 245 EXPECT_STREQ(cases[i].expectedProtocol, kurl.string().utf8().data()); 246 247 kurl.setHost(cases[i].host); 248 EXPECT_STREQ(cases[i].expectedHost, kurl.string().utf8().data()); 249 250 kurl.setPort(cases[i].port); 251 EXPECT_STREQ(cases[i].expectedPort, kurl.string().utf8().data()); 252 253 kurl.setUser(cases[i].user); 254 EXPECT_STREQ(cases[i].expectedUser, kurl.string().utf8().data()); 255 256 kurl.setPass(cases[i].pass); 257 EXPECT_STREQ(cases[i].expectedPass, kurl.string().utf8().data()); 258 259 kurl.setPath(cases[i].path); 260 EXPECT_STREQ(cases[i].expectedPath, kurl.string().utf8().data()); 261 262 kurl.setQuery(cases[i].query); 263 EXPECT_STREQ(cases[i].expectedQuery, kurl.string().utf8().data()); 264 265 // Refs are tested below. On the Safari 3.1 branch, we don't match their 266 // KURL since we integrated a fix from their trunk. 267 } 268} 269 270// Tests that KURL::decodeURLEscapeSequences works as expected 271TEST(KURLTest, Decode) 272{ 273 struct DecodeCase { 274 const char* input; 275 const char* output; 276 } decodeCases[] = { 277 {"hello, world", "hello, world"}, 278 {"%01%02%03%04%05%06%07%08%09%0a%0B%0C%0D%0e%0f/", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0B\x0C\x0D\x0e\x0f/"}, 279 {"%10%11%12%13%14%15%16%17%18%19%1a%1B%1C%1D%1e%1f/", "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1B\x1C\x1D\x1e\x1f/"}, 280 {"%20%21%22%23%24%25%26%27%28%29%2a%2B%2C%2D%2e%2f/", " !\"#$%&'()*+,-.//"}, 281 {"%30%31%32%33%34%35%36%37%38%39%3a%3B%3C%3D%3e%3f/", "0123456789:;<=>?/"}, 282 {"%40%41%42%43%44%45%46%47%48%49%4a%4B%4C%4D%4e%4f/", "@ABCDEFGHIJKLMNO/"}, 283 {"%50%51%52%53%54%55%56%57%58%59%5a%5B%5C%5D%5e%5f/", "PQRSTUVWXYZ[\\]^_/"}, 284 {"%60%61%62%63%64%65%66%67%68%69%6a%6B%6C%6D%6e%6f/", "`abcdefghijklmno/"}, 285 {"%70%71%72%73%74%75%76%77%78%79%7a%7B%7C%7D%7e%7f/", "pqrstuvwxyz{|}~\x7f/"}, 286 // Test un-UTF-8-ization. 287 {"%e4%bd%a0%e5%a5%bd", "\xe4\xbd\xa0\xe5\xa5\xbd"}, 288 }; 289 290 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(decodeCases); i++) { 291 WTF::String input(decodeCases[i].input); 292 WTF::String str = blink::decodeURLEscapeSequences(input); 293 EXPECT_STREQ(decodeCases[i].output, str.utf8().data()); 294 } 295 296 // Our decode should decode %00 297 WTF::String zero = blink::decodeURLEscapeSequences("%00"); 298 EXPECT_STRNE("%00", zero.utf8().data()); 299 300 // Test the error behavior for invalid UTF-8 (we differ from WebKit here). 301 WTF::String invalid = blink::decodeURLEscapeSequences( 302 "%e4%a0%e5%a5%bd"); 303 UChar invalidExpectedHelper[4] = { 0x00e4, 0x00a0, 0x597d, 0 }; 304 WTF::String invalidExpected( 305 reinterpret_cast<const ::UChar*>(invalidExpectedHelper), 306 3); 307 EXPECT_EQ(invalidExpected, invalid); 308} 309 310TEST(KURLTest, Encode) 311{ 312 struct EncodeCase { 313 const char* input; 314 const char* output; 315 } encode_cases[] = { 316 {"hello, world", "hello%2C%20world"}, 317 {"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 318 "%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F"}, 319 {"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 320 "%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F"}, 321 {" !\"#$%&'()*+,-./", "%20!%22%23%24%25%26%27()*%2B%2C-./"}, 322 {"0123456789:;<=>?", 323 "0123456789%3A%3B%3C%3D%3E%3F"}, 324 {"@ABCDEFGHIJKLMNO", 325 "%40ABCDEFGHIJKLMNO"}, 326 {"PQRSTUVWXYZ[\\]^_", 327 "PQRSTUVWXYZ%5B%5C%5D%5E_"}, 328 {"`abcdefghijklmno", 329 "%60abcdefghijklmno"}, 330 {"pqrstuvwxyz{|}~\x7f", 331 "pqrstuvwxyz%7B%7C%7D~%7F"}, 332 }; 333 334 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(encode_cases); i++) { 335 WTF::String input(encode_cases[i].input); 336 WTF::String expectedOutput(encode_cases[i].output); 337 WTF::String output = blink::encodeWithURLEscapeSequences(input); 338 EXPECT_EQ(expectedOutput, output); 339 } 340 341 // Our encode escapes NULLs for safety, so we need to check that too. 342 WTF::String input("\x00\x01", 2); 343 WTF::String reference("%00%01"); 344 345 WTF::String output = blink::encodeWithURLEscapeSequences(input); 346 EXPECT_EQ(reference, output); 347 348 // Also test that it gets converted to UTF-8 properly. 349 UChar wideInputHelper[3] = { 0x4f60, 0x597d, 0 }; 350 WTF::String wideInput( 351 reinterpret_cast<const ::UChar*>(wideInputHelper), 2); 352 WTF::String wideReference("%E4%BD%A0%E5%A5%BD"); 353 WTF::String wideOutput = 354 blink::encodeWithURLEscapeSequences(wideInput); 355 EXPECT_EQ(wideReference, wideOutput); 356} 357 358TEST(KURLTest, ResolveEmpty) 359{ 360 blink::KURL emptyBase; 361 362 // WebKit likes to be able to resolve absolute input agains empty base URLs, 363 // which would normally be invalid since the base URL is invalid. 364 const char abs[] = "http://www.google.com/"; 365 blink::KURL resolveAbs(emptyBase, abs); 366 EXPECT_TRUE(resolveAbs.isValid()); 367 EXPECT_STREQ(abs, resolveAbs.string().utf8().data()); 368 369 // Resolving a non-relative URL agains the empty one should still error. 370 const char rel[] = "foo.html"; 371 blink::KURL resolveErr(emptyBase, rel); 372 EXPECT_FALSE(resolveErr.isValid()); 373} 374 375// WebKit will make empty URLs and set components on them. kurl doesn't allow 376// replacements on invalid URLs, but here we do. 377TEST(KURLTest, ReplaceInvalid) 378{ 379 blink::KURL kurl; 380 381 EXPECT_FALSE(kurl.isValid()); 382 EXPECT_TRUE(kurl.isEmpty()); 383 EXPECT_STREQ("", kurl.string().utf8().data()); 384 385 kurl.setProtocol("http"); 386 // GKURL will say that a URL with just a scheme is invalid, KURL will not. 387 EXPECT_FALSE(kurl.isValid()); 388 EXPECT_FALSE(kurl.isEmpty()); 389 // At this point, we do things slightly differently if there is only a scheme. 390 // We check the results here to make it more obvious what is going on, but it 391 // shouldn't be a big deal if these change. 392 EXPECT_STREQ("http:", kurl.string().utf8().data()); 393 394 kurl.setHost("www.google.com"); 395 EXPECT_TRUE(kurl.isValid()); 396 EXPECT_FALSE(kurl.isEmpty()); 397 EXPECT_STREQ("http://www.google.com/", kurl.string().utf8().data()); 398 399 kurl.setPort(8000); 400 EXPECT_TRUE(kurl.isValid()); 401 EXPECT_FALSE(kurl.isEmpty()); 402 EXPECT_STREQ("http://www.google.com:8000/", kurl.string().utf8().data()); 403 404 kurl.setPath("/favicon.ico"); 405 EXPECT_TRUE(kurl.isValid()); 406 EXPECT_FALSE(kurl.isEmpty()); 407 EXPECT_STREQ("http://www.google.com:8000/favicon.ico", kurl.string().utf8().data()); 408 409 // Now let's test that giving an invalid replacement fails. Invalid 410 // protocols fail without modifying the URL, which should remain valid. 411 EXPECT_FALSE(kurl.setProtocol("f/sj#@")); 412 EXPECT_TRUE(kurl.isValid()); 413} 414 415TEST(KURLTest, Path) 416{ 417 const char initial[] = "http://www.google.com/path/foo"; 418 blink::KURL kurl(blink::ParsedURLString, initial); 419 420 // Clear by setting a null string. 421 WTF::String nullString; 422 EXPECT_TRUE(nullString.isNull()); 423 kurl.setPath(nullString); 424 EXPECT_STREQ("http://www.google.com/", kurl.string().utf8().data()); 425} 426 427// Test that setting the query to different things works. Thq query is handled 428// a littler differently than some of the other components. 429TEST(KURLTest, Query) 430{ 431 const char initial[] = "http://www.google.com/search?q=awesome"; 432 blink::KURL kurl(blink::ParsedURLString, initial); 433 434 // Clear by setting a null string. 435 WTF::String nullString; 436 EXPECT_TRUE(nullString.isNull()); 437 kurl.setQuery(nullString); 438 EXPECT_STREQ("http://www.google.com/search", kurl.string().utf8().data()); 439 440 // Clear by setting an empty string. 441 kurl = blink::KURL(blink::ParsedURLString, initial); 442 WTF::String emptyString(""); 443 EXPECT_FALSE(emptyString.isNull()); 444 kurl.setQuery(emptyString); 445 EXPECT_STREQ("http://www.google.com/search?", kurl.string().utf8().data()); 446 447 // Set with something that begins in a question mark. 448 const char question[] = "?foo=bar"; 449 kurl.setQuery(question); 450 EXPECT_STREQ("http://www.google.com/search?foo=bar", 451 kurl.string().utf8().data()); 452 453 // Set with something that doesn't begin in a question mark. 454 const char query[] = "foo=bar"; 455 kurl.setQuery(query); 456 EXPECT_STREQ("http://www.google.com/search?foo=bar", 457 kurl.string().utf8().data()); 458} 459 460TEST(KURLTest, Ref) 461{ 462 blink::KURL kurl(blink::ParsedURLString, "http://foo/bar#baz"); 463 464 // Basic ref setting. 465 blink::KURL cur(blink::ParsedURLString, "http://foo/bar"); 466 cur.setFragmentIdentifier("asdf"); 467 EXPECT_STREQ("http://foo/bar#asdf", cur.string().utf8().data()); 468 cur = kurl; 469 cur.setFragmentIdentifier("asdf"); 470 EXPECT_STREQ("http://foo/bar#asdf", cur.string().utf8().data()); 471 472 // Setting a ref to the empty string will set it to "#". 473 cur = blink::KURL(blink::ParsedURLString, "http://foo/bar"); 474 cur.setFragmentIdentifier(""); 475 EXPECT_STREQ("http://foo/bar#", cur.string().utf8().data()); 476 cur = kurl; 477 cur.setFragmentIdentifier(""); 478 EXPECT_STREQ("http://foo/bar#", cur.string().utf8().data()); 479 480 // Setting the ref to the null string will clear it altogether. 481 cur = blink::KURL(blink::ParsedURLString, "http://foo/bar"); 482 cur.setFragmentIdentifier(WTF::String()); 483 EXPECT_STREQ("http://foo/bar", cur.string().utf8().data()); 484 cur = kurl; 485 cur.setFragmentIdentifier(WTF::String()); 486 EXPECT_STREQ("http://foo/bar", cur.string().utf8().data()); 487} 488 489TEST(KURLTest, Empty) 490{ 491 blink::KURL kurl; 492 493 // First test that regular empty URLs are the same. 494 EXPECT_TRUE(kurl.isEmpty()); 495 EXPECT_FALSE(kurl.isValid()); 496 EXPECT_TRUE(kurl.isNull()); 497 EXPECT_TRUE(kurl.string().isNull()); 498 EXPECT_TRUE(kurl.string().isEmpty()); 499 500 // Test resolving a null URL on an empty string. 501 blink::KURL kurl2(kurl, ""); 502 EXPECT_FALSE(kurl2.isNull()); 503 EXPECT_TRUE(kurl2.isEmpty()); 504 EXPECT_FALSE(kurl2.isValid()); 505 EXPECT_FALSE(kurl2.string().isNull()); 506 EXPECT_TRUE(kurl2.string().isEmpty()); 507 EXPECT_FALSE(kurl2.string().isNull()); 508 EXPECT_TRUE(kurl2.string().isEmpty()); 509 510 // Resolve the null URL on a null string. 511 blink::KURL kurl22(kurl, WTF::String()); 512 EXPECT_FALSE(kurl22.isNull()); 513 EXPECT_TRUE(kurl22.isEmpty()); 514 EXPECT_FALSE(kurl22.isValid()); 515 EXPECT_FALSE(kurl22.string().isNull()); 516 EXPECT_TRUE(kurl22.string().isEmpty()); 517 EXPECT_FALSE(kurl22.string().isNull()); 518 EXPECT_TRUE(kurl22.string().isEmpty()); 519 520 // Test non-hierarchical schemes resolving. The actual URLs will be different. 521 // WebKit's one will set the string to "something.gif" and we'll set it to an 522 // empty string. I think either is OK, so we just check our behavior. 523 blink::KURL kurl3(blink::KURL(blink::ParsedURLString, "data:foo"), 524 "something.gif"); 525 EXPECT_TRUE(kurl3.isEmpty()); 526 EXPECT_FALSE(kurl3.isValid()); 527 528 // Test for weird isNull string input, 529 // see: http://bugs.webkit.org/show_bug.cgi?id=16487 530 blink::KURL kurl4(blink::ParsedURLString, kurl.string()); 531 EXPECT_TRUE(kurl4.isEmpty()); 532 EXPECT_FALSE(kurl4.isValid()); 533 EXPECT_TRUE(kurl4.string().isNull()); 534 EXPECT_TRUE(kurl4.string().isEmpty()); 535 536 // Resolving an empty URL on an invalid string. 537 blink::KURL kurl5(blink::KURL(), "foo.js"); 538 // We'll be empty in this case, but KURL won't be. Should be OK. 539 // EXPECT_EQ(kurl5.isEmpty(), kurl5.isEmpty()); 540 // EXPECT_EQ(kurl5.string().isEmpty(), kurl5.string().isEmpty()); 541 EXPECT_FALSE(kurl5.isValid()); 542 EXPECT_FALSE(kurl5.string().isNull()); 543 544 // Empty string as input 545 blink::KURL kurl6(blink::ParsedURLString, ""); 546 EXPECT_TRUE(kurl6.isEmpty()); 547 EXPECT_FALSE(kurl6.isValid()); 548 EXPECT_FALSE(kurl6.string().isNull()); 549 EXPECT_TRUE(kurl6.string().isEmpty()); 550 551 // Non-empty but invalid C string as input. 552 blink::KURL kurl7(blink::ParsedURLString, "foo.js"); 553 // WebKit will actually say this URL has the string "foo.js" but is invalid. 554 // We don't do that. 555 // EXPECT_EQ(kurl7.isEmpty(), kurl7.isEmpty()); 556 EXPECT_FALSE(kurl7.isValid()); 557 EXPECT_FALSE(kurl7.string().isNull()); 558} 559 560TEST(KURLTest, UserPass) 561{ 562 const char* src = "http://user:pass@google.com/"; 563 blink::KURL kurl(blink::ParsedURLString, src); 564 565 // Clear just the username. 566 kurl.setUser(""); 567 EXPECT_EQ("http://:pass@google.com/", kurl.string()); 568 569 // Clear just the password. 570 kurl = blink::KURL(blink::ParsedURLString, src); 571 kurl.setPass(""); 572 EXPECT_EQ("http://user@google.com/", kurl.string()); 573 574 // Now clear both. 575 kurl.setUser(""); 576 EXPECT_EQ("http://google.com/", kurl.string()); 577} 578 579TEST(KURLTest, Offsets) 580{ 581 const char* src1 = "http://user:pass@google.com/foo/bar.html?baz=query#ref"; 582 blink::KURL kurl1(blink::ParsedURLString, src1); 583 584 EXPECT_EQ(17u, kurl1.hostStart()); 585 EXPECT_EQ(27u, kurl1.hostEnd()); 586 EXPECT_EQ(27u, kurl1.pathStart()); 587 EXPECT_EQ(40u, kurl1.pathEnd()); 588 EXPECT_EQ(32u, kurl1.pathAfterLastSlash()); 589 590 const char* src2 = "http://google.com/foo/"; 591 blink::KURL kurl2(blink::ParsedURLString, src2); 592 593 EXPECT_EQ(7u, kurl2.hostStart()); 594 EXPECT_EQ(17u, kurl2.hostEnd()); 595 EXPECT_EQ(17u, kurl2.pathStart()); 596 EXPECT_EQ(22u, kurl2.pathEnd()); 597 EXPECT_EQ(22u, kurl2.pathAfterLastSlash()); 598 599 const char* src3 = "javascript:foobar"; 600 blink::KURL kurl3(blink::ParsedURLString, src3); 601 602 EXPECT_EQ(11u, kurl3.hostStart()); 603 EXPECT_EQ(11u, kurl3.hostEnd()); 604 EXPECT_EQ(11u, kurl3.pathStart()); 605 EXPECT_EQ(17u, kurl3.pathEnd()); 606 EXPECT_EQ(11u, kurl3.pathAfterLastSlash()); 607} 608 609TEST(KURLTest, DeepCopy) 610{ 611 const char url[] = "http://www.google.com/"; 612 blink::KURL src(blink::ParsedURLString, url); 613 EXPECT_TRUE(src.string() == url); // This really just initializes the cache. 614 blink::KURL dest = src.copy(); 615 EXPECT_TRUE(dest.string() == url); // This really just initializes the cache. 616 617 // The pointers should be different for both UTF-8 and UTF-16. 618 EXPECT_NE(dest.string().impl(), src.string().impl()); 619} 620 621TEST(KURLTest, DeepCopyInnerURL) 622{ 623 const char url[] = "filesystem:http://www.google.com/temporary/test.txt"; 624 const char innerURL[] = "http://www.google.com/temporary"; 625 blink::KURL src(blink::ParsedURLString, url); 626 EXPECT_TRUE(src.string() == url); 627 EXPECT_TRUE(src.innerURL()->string() == innerURL); 628 blink::KURL dest = src.copy(); 629 EXPECT_TRUE(dest.string() == url); 630 EXPECT_TRUE(dest.innerURL()->string() == innerURL); 631} 632 633TEST(KURLTest, LastPathComponent) 634{ 635 blink::KURL url1(blink::ParsedURLString, "http://host/path/to/file.txt"); 636 EXPECT_EQ("file.txt", url1.lastPathComponent()); 637 638 blink::KURL invalidUTF8(blink::ParsedURLString, "http://a@9%aa%:/path/to/file.txt"); 639 EXPECT_EQ(String(), invalidUTF8.lastPathComponent()); 640} 641 642TEST(KURLTest, IsHierarchical) 643{ 644 blink::KURL url1(blink::ParsedURLString, "http://host/path/to/file.txt"); 645 EXPECT_TRUE(url1.isHierarchical()); 646 647 blink::KURL invalidUTF8(blink::ParsedURLString, "http://a@9%aa%:/path/to/file.txt"); 648 EXPECT_FALSE(invalidUTF8.isHierarchical()); 649} 650 651TEST(KURLTest, PathAfterLastSlash) 652{ 653 blink::KURL url1(blink::ParsedURLString, "http://host/path/to/file.txt"); 654 EXPECT_EQ(20u, url1.pathAfterLastSlash()); 655 656 blink::KURL invalidUTF8(blink::ParsedURLString, "http://a@9%aa%:/path/to/file.txt"); 657 EXPECT_EQ(0u, invalidUTF8.pathAfterLastSlash()); 658} 659 660TEST(KURLTest, ProtocolIsInHTTPFamily) 661{ 662 blink::KURL url1(blink::ParsedURLString, "http://host/path/to/file.txt"); 663 EXPECT_TRUE(url1.protocolIsInHTTPFamily()); 664 665 blink::KURL invalidUTF8(blink::ParsedURLString, "http://a@9%aa%:/path/to/file.txt"); 666 EXPECT_FALSE(invalidUTF8.protocolIsInHTTPFamily()); 667} 668 669TEST(KURLTest, ProtocolIs) 670{ 671 blink::KURL url1(blink::ParsedURLString, "foo://bar"); 672 EXPECT_TRUE(url1.protocolIs("foo")); 673 EXPECT_FALSE(url1.protocolIs("foo-bar")); 674 675 blink::KURL url2(blink::ParsedURLString, "foo-bar:"); 676 EXPECT_TRUE(url2.protocolIs("foo-bar")); 677 EXPECT_FALSE(url2.protocolIs("foo")); 678 679 blink::KURL invalidUTF8(blink::ParsedURLString, "http://a@9%aa%:"); 680 EXPECT_FALSE(invalidUTF8.protocolIs("http")); 681 EXPECT_TRUE(invalidUTF8.protocolIs("")); 682} 683 684TEST(KURLTest, strippedForUseAsReferrer) 685{ 686 struct ReferrerCase { 687 const char* input; 688 const char* output; 689 } referrerCases[] = { 690 {"data:text/html;charset=utf-8,<html></html>", ""}, 691 {"javascript:void(0);", ""}, 692 {"about:config", ""}, 693 {"https://www.google.com/", "https://www.google.com/"}, 694 {"http://me@news.google.com:8888/", "http://news.google.com:8888/"}, 695 {"http://:pass@news.google.com:8888/foo", "http://news.google.com:8888/foo"}, 696 {"http://me:pass@news.google.com:8888/", "http://news.google.com:8888/"}, 697 {"https://www.google.com/a?f#b", "https://www.google.com/a?f"}, 698 }; 699 700 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(referrerCases); i++) { 701 blink::KURL kurl(blink::ParsedURLString, referrerCases[i].input); 702 WTF::String referrer = kurl.strippedForUseAsReferrer(); 703 EXPECT_STREQ(referrerCases[i].output, referrer.utf8().data()); 704 } 705} 706 707} // namespace 708