1{ 2 "comment": [ 3 "# Pulled from https://github.com/web-platform-tests/wpt/blob/befe66343e5f21dc464c8c772c6d20695936714f/url/resources/setters_tests.json", 4 "## Tests for setters of https://url.spec.whatwg.org/#urlutils-members", 5 "", 6 "This file contains a JSON object.", 7 "Other than 'comment', each key is an attribute of the `URL` interface", 8 "defined in WHATWG’s URL Standard.", 9 "The values are arrays of test case objects for that attribute.", 10 "", 11 "To run a test case for the attribute `attr`:", 12 "", 13 "* Create a new `URL` object with the value for the 'href' key", 14 " the constructor single parameter. (Without a base URL.)", 15 " This must not throw.", 16 "* Set the attribute `attr` to (invoke its setter with)", 17 " with the value of for 'new_value' key.", 18 "* The value for the 'expected' key is another object.", 19 " For each `key` / `value` pair of that object,", 20 " get the attribute `key` (invoke its getter).", 21 " The returned string must be equal to `value`.", 22 "", 23 "Note: the 'href' setter is already covered by urltestdata.json." 24 ], 25 "protocol": [ 26 { 27 "comment": "The empty string is not a valid scheme. Setter leaves the URL unchanged.", 28 "href": "a://example.net", 29 "new_value": "", 30 "expected": { 31 "href": "a://example.net", 32 "protocol": "a:" 33 } 34 }, 35 { 36 "href": "a://example.net", 37 "new_value": "b", 38 "expected": { 39 "href": "b://example.net", 40 "protocol": "b:" 41 } 42 }, 43 { 44 "href": "javascript:alert(1)", 45 "new_value": "defuse", 46 "expected": { 47 "href": "defuse:alert(1)", 48 "protocol": "defuse:" 49 } 50 }, 51 { 52 "comment": "Upper-case ASCII is lower-cased", 53 "href": "a://example.net", 54 "new_value": "B", 55 "expected": { 56 "href": "b://example.net", 57 "protocol": "b:" 58 } 59 }, 60 { 61 "comment": "Non-ASCII is rejected", 62 "href": "a://example.net", 63 "new_value": "é", 64 "expected": { 65 "href": "a://example.net", 66 "protocol": "a:" 67 } 68 }, 69 { 70 "comment": "No leading digit", 71 "href": "a://example.net", 72 "new_value": "0b", 73 "expected": { 74 "href": "a://example.net", 75 "protocol": "a:" 76 } 77 }, 78 { 79 "comment": "No leading punctuation", 80 "href": "a://example.net", 81 "new_value": "+b", 82 "expected": { 83 "href": "a://example.net", 84 "protocol": "a:" 85 } 86 }, 87 { 88 "href": "a://example.net", 89 "new_value": "bC0+-.", 90 "expected": { 91 "href": "bc0+-.://example.net", 92 "protocol": "bc0+-.:" 93 } 94 }, 95 { 96 "comment": "Only some punctuation is acceptable", 97 "href": "a://example.net", 98 "new_value": "b,c", 99 "expected": { 100 "href": "a://example.net", 101 "protocol": "a:" 102 } 103 }, 104 { 105 "comment": "Non-ASCII is rejected", 106 "href": "a://example.net", 107 "new_value": "bé", 108 "expected": { 109 "href": "a://example.net", 110 "protocol": "a:" 111 } 112 }, 113 { 114 "comment": "Can’t switch from URL containing username/password/port to file", 115 "href": "http://test@example.net", 116 "new_value": "file", 117 "expected": { 118 "href": "http://test@example.net/", 119 "protocol": "http:" 120 } 121 }, 122 { 123 "href": "https://example.net:1234", 124 "new_value": "file", 125 "expected": { 126 "href": "https://example.net:1234/", 127 "protocol": "https:" 128 } 129 }, 130 { 131 "href": "wss://x:x@example.net:1234", 132 "new_value": "file", 133 "expected": { 134 "href": "wss://x:x@example.net:1234/", 135 "protocol": "wss:" 136 } 137 }, 138 { 139 "comment": "Can’t switch from file URL with no host", 140 "href": "file://localhost/", 141 "new_value": "http", 142 "expected": { 143 "href": "file:///", 144 "protocol": "file:" 145 } 146 }, 147 { 148 "href": "file:///test", 149 "new_value": "https", 150 "expected": { 151 "href": "file:///test", 152 "protocol": "file:" 153 } 154 }, 155 { 156 "href": "file:", 157 "new_value": "wss", 158 "expected": { 159 "href": "file:///", 160 "protocol": "file:" 161 } 162 }, 163 { 164 "comment": "Can’t switch from special scheme to non-special", 165 "href": "http://example.net", 166 "new_value": "b", 167 "expected": { 168 "href": "http://example.net/", 169 "protocol": "http:" 170 } 171 }, 172 { 173 "href": "file://hi/path", 174 "new_value": "s", 175 "expected": { 176 "href": "file://hi/path", 177 "protocol": "file:" 178 } 179 }, 180 { 181 "href": "https://example.net", 182 "new_value": "s", 183 "expected": { 184 "href": "https://example.net/", 185 "protocol": "https:" 186 } 187 }, 188 { 189 "href": "ftp://example.net", 190 "new_value": "test", 191 "expected": { 192 "href": "ftp://example.net/", 193 "protocol": "ftp:" 194 } 195 }, 196 { 197 "comment": "Cannot-be-a-base URL doesn’t have a host, but URL in a special scheme must.", 198 "href": "mailto:me@example.net", 199 "new_value": "http", 200 "expected": { 201 "href": "mailto:me@example.net", 202 "protocol": "mailto:" 203 } 204 }, 205 { 206 "comment": "Can’t switch from non-special scheme to special", 207 "href": "ssh://me@example.net", 208 "new_value": "http", 209 "expected": { 210 "href": "ssh://me@example.net", 211 "protocol": "ssh:" 212 } 213 }, 214 { 215 "href": "ssh://me@example.net", 216 "new_value": "https", 217 "expected": { 218 "href": "ssh://me@example.net", 219 "protocol": "ssh:" 220 } 221 }, 222 { 223 "href": "ssh://me@example.net", 224 "new_value": "file", 225 "expected": { 226 "href": "ssh://me@example.net", 227 "protocol": "ssh:" 228 } 229 }, 230 { 231 "href": "ssh://example.net", 232 "new_value": "file", 233 "expected": { 234 "href": "ssh://example.net", 235 "protocol": "ssh:" 236 } 237 }, 238 { 239 "href": "nonsense:///test", 240 "new_value": "https", 241 "expected": { 242 "href": "nonsense:///test", 243 "protocol": "nonsense:" 244 } 245 }, 246 { 247 "comment": "Stuff after the first ':' is ignored", 248 "href": "http://example.net", 249 "new_value": "https:foo : bar", 250 "expected": { 251 "href": "https://example.net/", 252 "protocol": "https:" 253 } 254 }, 255 { 256 "comment": "Stuff after the first ':' is ignored", 257 "href": "data:text/html,<p>Test", 258 "new_value": "view-source+data:foo : bar", 259 "expected": { 260 "href": "view-source+data:text/html,<p>Test", 261 "protocol": "view-source+data:" 262 } 263 }, 264 { 265 "comment": "Port is set to null if it is the default for new scheme.", 266 "href": "http://foo.com:443/", 267 "new_value": "https", 268 "expected": { 269 "href": "https://foo.com/", 270 "protocol": "https:", 271 "port": "" 272 } 273 }, 274 { 275 "comment": "Tab and newline are stripped", 276 "href": "http://test/", 277 "new_value": "h\u000D\u000Att\u0009ps", 278 "expected": { 279 "href": "https://test/", 280 "protocol": "https:", 281 "port": "" 282 } 283 }, 284 { 285 "href": "http://test/", 286 "new_value": "https\u000D", 287 "expected": { 288 "href": "https://test/", 289 "protocol": "https:" 290 } 291 }, 292 { 293 "comment": "Non-tab/newline C0 controls result in no-op", 294 "href": "http://test/", 295 "new_value": "https\u0000", 296 "expected": { 297 "href": "http://test/", 298 "protocol": "http:" 299 } 300 }, 301 { 302 "href": "http://test/", 303 "new_value": "https\u000C", 304 "expected": { 305 "href": "http://test/", 306 "protocol": "http:" 307 } 308 }, 309 { 310 "href": "http://test/", 311 "new_value": "https\u000E", 312 "expected": { 313 "href": "http://test/", 314 "protocol": "http:" 315 } 316 }, 317 { 318 "href": "http://test/", 319 "new_value": "https\u0020", 320 "expected": { 321 "href": "http://test/", 322 "protocol": "http:" 323 } 324 } 325 ], 326 "username": [ 327 { 328 "comment": "No host means no username", 329 "href": "file:///home/you/index.html", 330 "new_value": "me", 331 "expected": { 332 "href": "file:///home/you/index.html", 333 "username": "" 334 } 335 }, 336 { 337 "comment": "No host means no username", 338 "href": "unix:/run/foo.socket", 339 "new_value": "me", 340 "expected": { 341 "href": "unix:/run/foo.socket", 342 "username": "" 343 } 344 }, 345 { 346 "comment": "Cannot-be-a-base means no username", 347 "href": "mailto:you@example.net", 348 "new_value": "me", 349 "expected": { 350 "href": "mailto:you@example.net", 351 "username": "" 352 } 353 }, 354 { 355 "href": "javascript:alert(1)", 356 "new_value": "wario", 357 "expected": { 358 "href": "javascript:alert(1)", 359 "username": "" 360 } 361 }, 362 { 363 "href": "http://example.net", 364 "new_value": "me", 365 "expected": { 366 "href": "http://me@example.net/", 367 "username": "me" 368 } 369 }, 370 { 371 "href": "http://:secret@example.net", 372 "new_value": "me", 373 "expected": { 374 "href": "http://me:secret@example.net/", 375 "username": "me" 376 } 377 }, 378 { 379 "href": "http://me@example.net", 380 "new_value": "", 381 "expected": { 382 "href": "http://example.net/", 383 "username": "" 384 } 385 }, 386 { 387 "href": "http://me:secret@example.net", 388 "new_value": "", 389 "expected": { 390 "href": "http://:secret@example.net/", 391 "username": "" 392 } 393 }, 394 { 395 "comment": "UTF-8 percent encoding with the userinfo encode set.", 396 "href": "http://example.net", 397 "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé", 398 "expected": { 399 "href": "http://%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9@example.net/", 400 "username": "%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9" 401 } 402 }, 403 { 404 "comment": "Bytes already percent-encoded are left as-is.", 405 "href": "http://example.net", 406 "new_value": "%c3%89té", 407 "expected": { 408 "href": "http://%c3%89t%C3%A9@example.net/", 409 "username": "%c3%89t%C3%A9" 410 } 411 }, 412 { 413 "href": "sc:///", 414 "new_value": "x", 415 "expected": { 416 "href": "sc:///", 417 "username": "" 418 } 419 }, 420 { 421 "href": "javascript://x/", 422 "new_value": "wario", 423 "expected": { 424 "href": "javascript://wario@x/", 425 "username": "wario" 426 } 427 }, 428 { 429 "href": "file://test/", 430 "new_value": "test", 431 "expected": { 432 "href": "file://test/", 433 "username": "" 434 } 435 } 436 ], 437 "password": [ 438 { 439 "comment": "No host means no password", 440 "href": "file:///home/me/index.html", 441 "new_value": "secret", 442 "expected": { 443 "href": "file:///home/me/index.html", 444 "password": "" 445 } 446 }, 447 { 448 "comment": "No host means no password", 449 "href": "unix:/run/foo.socket", 450 "new_value": "secret", 451 "expected": { 452 "href": "unix:/run/foo.socket", 453 "password": "" 454 } 455 }, 456 { 457 "comment": "Cannot-be-a-base means no password", 458 "href": "mailto:me@example.net", 459 "new_value": "secret", 460 "expected": { 461 "href": "mailto:me@example.net", 462 "password": "" 463 } 464 }, 465 { 466 "href": "http://example.net", 467 "new_value": "secret", 468 "expected": { 469 "href": "http://:secret@example.net/", 470 "password": "secret" 471 } 472 }, 473 { 474 "href": "http://me@example.net", 475 "new_value": "secret", 476 "expected": { 477 "href": "http://me:secret@example.net/", 478 "password": "secret" 479 } 480 }, 481 { 482 "href": "http://:secret@example.net", 483 "new_value": "", 484 "expected": { 485 "href": "http://example.net/", 486 "password": "" 487 } 488 }, 489 { 490 "href": "http://me:secret@example.net", 491 "new_value": "", 492 "expected": { 493 "href": "http://me@example.net/", 494 "password": "" 495 } 496 }, 497 { 498 "comment": "UTF-8 percent encoding with the userinfo encode set.", 499 "href": "http://example.net", 500 "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé", 501 "expected": { 502 "href": "http://:%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9@example.net/", 503 "password": "%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9" 504 } 505 }, 506 { 507 "comment": "Bytes already percent-encoded are left as-is.", 508 "href": "http://example.net", 509 "new_value": "%c3%89té", 510 "expected": { 511 "href": "http://:%c3%89t%C3%A9@example.net/", 512 "password": "%c3%89t%C3%A9" 513 } 514 }, 515 { 516 "href": "sc:///", 517 "new_value": "x", 518 "expected": { 519 "href": "sc:///", 520 "password": "" 521 } 522 }, 523 { 524 "href": "javascript://x/", 525 "new_value": "bowser", 526 "expected": { 527 "href": "javascript://:bowser@x/", 528 "password": "bowser" 529 } 530 }, 531 { 532 "href": "file://test/", 533 "new_value": "test", 534 "expected": { 535 "href": "file://test/", 536 "password": "" 537 } 538 } 539 ], 540 "host": [ 541 { 542 "comment": "Non-special scheme", 543 "href": "sc://x/", 544 "new_value": "\u0000", 545 "expected": { 546 "href": "sc://x/", 547 "host": "x", 548 "hostname": "x" 549 } 550 }, 551 { 552 "href": "sc://x/", 553 "new_value": "\u0009", 554 "expected": { 555 "href": "sc:///", 556 "host": "", 557 "hostname": "" 558 } 559 }, 560 { 561 "href": "sc://x/", 562 "new_value": "\u000A", 563 "expected": { 564 "href": "sc:///", 565 "host": "", 566 "hostname": "" 567 } 568 }, 569 { 570 "href": "sc://x/", 571 "new_value": "\u000D", 572 "expected": { 573 "href": "sc:///", 574 "host": "", 575 "hostname": "" 576 } 577 }, 578 { 579 "href": "sc://x/", 580 "new_value": " ", 581 "expected": { 582 "href": "sc://x/", 583 "host": "x", 584 "hostname": "x" 585 } 586 }, 587 { 588 "href": "sc://x/", 589 "new_value": "#", 590 "expected": { 591 "href": "sc:///", 592 "host": "", 593 "hostname": "" 594 } 595 }, 596 { 597 "href": "sc://x/", 598 "new_value": "/", 599 "expected": { 600 "href": "sc:///", 601 "host": "", 602 "hostname": "" 603 } 604 }, 605 { 606 "href": "sc://x/", 607 "new_value": "?", 608 "expected": { 609 "href": "sc:///", 610 "host": "", 611 "hostname": "" 612 } 613 }, 614 { 615 "href": "sc://x/", 616 "new_value": "@", 617 "expected": { 618 "href": "sc://x/", 619 "host": "x", 620 "hostname": "x" 621 } 622 }, 623 { 624 "href": "sc://x/", 625 "new_value": "ß", 626 "expected": { 627 "href": "sc://%C3%9F/", 628 "host": "%C3%9F", 629 "hostname": "%C3%9F" 630 } 631 }, 632 { 633 "comment": "IDNA Nontransitional_Processing", 634 "href": "https://x/", 635 "new_value": "ß", 636 "expected": { 637 "href": "https://xn--zca/", 638 "host": "xn--zca", 639 "hostname": "xn--zca" 640 } 641 }, 642 { 643 "comment": "Cannot-be-a-base means no host", 644 "href": "mailto:me@example.net", 645 "new_value": "example.com", 646 "expected": { 647 "href": "mailto:me@example.net", 648 "host": "" 649 } 650 }, 651 { 652 "comment": "Cannot-be-a-base means no host", 653 "href": "data:text/plain,Stuff", 654 "new_value": "example.net", 655 "expected": { 656 "href": "data:text/plain,Stuff", 657 "host": "" 658 } 659 }, 660 { 661 "href": "http://example.net", 662 "new_value": "example.com:8080", 663 "expected": { 664 "href": "http://example.com:8080/", 665 "host": "example.com:8080", 666 "hostname": "example.com", 667 "port": "8080" 668 } 669 }, 670 { 671 "comment": "Port number is unchanged if not specified in the new value", 672 "href": "http://example.net:8080", 673 "new_value": "example.com", 674 "expected": { 675 "href": "http://example.com:8080/", 676 "host": "example.com:8080", 677 "hostname": "example.com", 678 "port": "8080" 679 } 680 }, 681 { 682 "comment": "Port number is unchanged if not specified", 683 "href": "http://example.net:8080", 684 "new_value": "example.com:", 685 "expected": { 686 "href": "http://example.com:8080/", 687 "host": "example.com:8080", 688 "hostname": "example.com", 689 "port": "8080" 690 } 691 }, 692 { 693 "comment": "The empty host is not valid for special schemes", 694 "href": "http://example.net", 695 "new_value": "", 696 "expected": { 697 "href": "http://example.net/", 698 "host": "example.net" 699 } 700 }, 701 { 702 "comment": "The empty host is OK for non-special schemes", 703 "href": "view-source+http://example.net/foo", 704 "new_value": "", 705 "expected": { 706 "href": "view-source+http:///foo", 707 "host": "" 708 } 709 }, 710 { 711 "comment": "Path-only URLs can gain a host", 712 "href": "a:/foo", 713 "new_value": "example.net", 714 "expected": { 715 "href": "a://example.net/foo", 716 "host": "example.net" 717 } 718 }, 719 { 720 "comment": "IPv4 address syntax is normalized", 721 "href": "http://example.net", 722 "new_value": "0x7F000001:8080", 723 "expected": { 724 "href": "http://127.0.0.1:8080/", 725 "host": "127.0.0.1:8080", 726 "hostname": "127.0.0.1", 727 "port": "8080" 728 } 729 }, 730 { 731 "comment": "IPv6 address syntax is normalized", 732 "href": "http://example.net", 733 "new_value": "[::0:01]:2", 734 "expected": { 735 "href": "http://[::1]:2/", 736 "host": "[::1]:2", 737 "hostname": "[::1]", 738 "port": "2" 739 } 740 }, 741 { 742 "comment": "IPv6 literal address with port, crbug.com/1012416", 743 "href": "http://example.net", 744 "new_value": "[2001:db8::2]:4002", 745 "expected": { 746 "href": "http://[2001:db8::2]:4002/", 747 "host": "[2001:db8::2]:4002", 748 "hostname": "[2001:db8::2]", 749 "port": "4002" 750 } 751 }, 752 { 753 "comment": "Default port number is removed", 754 "href": "http://example.net", 755 "new_value": "example.com:80", 756 "expected": { 757 "href": "http://example.com/", 758 "host": "example.com", 759 "hostname": "example.com", 760 "port": "" 761 } 762 }, 763 { 764 "comment": "Default port number is removed", 765 "href": "https://example.net", 766 "new_value": "example.com:443", 767 "expected": { 768 "href": "https://example.com/", 769 "host": "example.com", 770 "hostname": "example.com", 771 "port": "" 772 } 773 }, 774 { 775 "comment": "Default port number is only removed for the relevant scheme", 776 "href": "https://example.net", 777 "new_value": "example.com:80", 778 "expected": { 779 "href": "https://example.com:80/", 780 "host": "example.com:80", 781 "hostname": "example.com", 782 "port": "80" 783 } 784 }, 785 { 786 "comment": "Port number is removed if new port is scheme default and existing URL has a non-default port", 787 "href": "http://example.net:8080", 788 "new_value": "example.com:80", 789 "expected": { 790 "href": "http://example.com/", 791 "host": "example.com", 792 "hostname": "example.com", 793 "port": "" 794 } 795 }, 796 { 797 "comment": "Stuff after a / delimiter is ignored", 798 "href": "http://example.net/path", 799 "new_value": "example.com/stuff", 800 "expected": { 801 "href": "http://example.com/path", 802 "host": "example.com", 803 "hostname": "example.com", 804 "port": "" 805 } 806 }, 807 { 808 "comment": "Stuff after a / delimiter is ignored", 809 "href": "http://example.net/path", 810 "new_value": "example.com:8080/stuff", 811 "expected": { 812 "href": "http://example.com:8080/path", 813 "host": "example.com:8080", 814 "hostname": "example.com", 815 "port": "8080" 816 } 817 }, 818 { 819 "comment": "Stuff after a ? delimiter is ignored", 820 "href": "http://example.net/path", 821 "new_value": "example.com?stuff", 822 "expected": { 823 "href": "http://example.com/path", 824 "host": "example.com", 825 "hostname": "example.com", 826 "port": "" 827 } 828 }, 829 { 830 "comment": "Stuff after a ? delimiter is ignored", 831 "href": "http://example.net/path", 832 "new_value": "example.com:8080?stuff", 833 "expected": { 834 "href": "http://example.com:8080/path", 835 "host": "example.com:8080", 836 "hostname": "example.com", 837 "port": "8080" 838 } 839 }, 840 { 841 "comment": "Stuff after a # delimiter is ignored", 842 "href": "http://example.net/path", 843 "new_value": "example.com#stuff", 844 "expected": { 845 "href": "http://example.com/path", 846 "host": "example.com", 847 "hostname": "example.com", 848 "port": "" 849 } 850 }, 851 { 852 "comment": "Stuff after a # delimiter is ignored", 853 "href": "http://example.net/path", 854 "new_value": "example.com:8080#stuff", 855 "expected": { 856 "href": "http://example.com:8080/path", 857 "host": "example.com:8080", 858 "hostname": "example.com", 859 "port": "8080" 860 } 861 }, 862 { 863 "comment": "Stuff after a \\ delimiter is ignored for special schemes", 864 "href": "http://example.net/path", 865 "new_value": "example.com\\stuff", 866 "expected": { 867 "href": "http://example.com/path", 868 "host": "example.com", 869 "hostname": "example.com", 870 "port": "" 871 } 872 }, 873 { 874 "comment": "Stuff after a \\ delimiter is ignored for special schemes", 875 "href": "http://example.net/path", 876 "new_value": "example.com:8080\\stuff", 877 "expected": { 878 "href": "http://example.com:8080/path", 879 "host": "example.com:8080", 880 "hostname": "example.com", 881 "port": "8080" 882 } 883 }, 884 { 885 "comment": "\\ is not a delimiter for non-special schemes, but still forbidden in hosts", 886 "href": "view-source+http://example.net/path", 887 "new_value": "example.com\\stuff", 888 "expected": { 889 "href": "view-source+http://example.net/path", 890 "host": "example.net", 891 "hostname": "example.net", 892 "port": "" 893 } 894 }, 895 { 896 "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", 897 "href": "view-source+http://example.net/path", 898 "new_value": "example.com:8080stuff2", 899 "expected": { 900 "href": "view-source+http://example.com:8080/path", 901 "host": "example.com:8080", 902 "hostname": "example.com", 903 "port": "8080" 904 } 905 }, 906 { 907 "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", 908 "href": "http://example.net/path", 909 "new_value": "example.com:8080stuff2", 910 "expected": { 911 "href": "http://example.com:8080/path", 912 "host": "example.com:8080", 913 "hostname": "example.com", 914 "port": "8080" 915 } 916 }, 917 { 918 "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", 919 "href": "http://example.net/path", 920 "new_value": "example.com:8080+2", 921 "expected": { 922 "href": "http://example.com:8080/path", 923 "host": "example.com:8080", 924 "hostname": "example.com", 925 "port": "8080" 926 } 927 }, 928 { 929 "comment": "Port numbers are 16 bit integers", 930 "href": "http://example.net/path", 931 "new_value": "example.com:65535", 932 "expected": { 933 "href": "http://example.com:65535/path", 934 "host": "example.com:65535", 935 "hostname": "example.com", 936 "port": "65535" 937 } 938 }, 939 { 940 "comment": "Port numbers are 16 bit integers, overflowing is an error. Hostname is still set, though.", 941 "href": "http://example.net/path", 942 "new_value": "example.com:65536", 943 "expected": { 944 "href": "http://example.com/path", 945 "host": "example.com", 946 "hostname": "example.com", 947 "port": "" 948 } 949 }, 950 { 951 "comment": "Broken IPv6", 952 "href": "http://example.net/", 953 "new_value": "[google.com]", 954 "expected": { 955 "href": "http://example.net/", 956 "host": "example.net", 957 "hostname": "example.net" 958 } 959 }, 960 { 961 "href": "http://example.net/", 962 "new_value": "[::1.2.3.4x]", 963 "expected": { 964 "href": "http://example.net/", 965 "host": "example.net", 966 "hostname": "example.net" 967 } 968 }, 969 { 970 "href": "http://example.net/", 971 "new_value": "[::1.2.3.]", 972 "expected": { 973 "href": "http://example.net/", 974 "host": "example.net", 975 "hostname": "example.net" 976 } 977 }, 978 { 979 "href": "http://example.net/", 980 "new_value": "[::1.2.]", 981 "expected": { 982 "href": "http://example.net/", 983 "host": "example.net", 984 "hostname": "example.net" 985 } 986 }, 987 { 988 "href": "http://example.net/", 989 "new_value": "[::1.]", 990 "expected": { 991 "href": "http://example.net/", 992 "host": "example.net", 993 "hostname": "example.net" 994 } 995 }, 996 { 997 "href": "file://y/", 998 "new_value": "x:123", 999 "expected": { 1000 "href": "file://y/", 1001 "host": "y", 1002 "hostname": "y", 1003 "port": "" 1004 } 1005 }, 1006 { 1007 "href": "file://y/", 1008 "new_value": "loc%41lhost", 1009 "expected": { 1010 "href": "file:///", 1011 "host": "", 1012 "hostname": "", 1013 "port": "" 1014 } 1015 }, 1016 { 1017 "href": "file://hi/x", 1018 "new_value": "", 1019 "expected": { 1020 "href": "file:///x", 1021 "host": "", 1022 "hostname": "", 1023 "port": "" 1024 } 1025 }, 1026 { 1027 "href": "sc://test@test/", 1028 "new_value": "", 1029 "expected": { 1030 "href": "sc://test@test/", 1031 "host": "test", 1032 "hostname": "test", 1033 "username": "test" 1034 } 1035 }, 1036 { 1037 "href": "sc://test:12/", 1038 "new_value": "", 1039 "expected": { 1040 "href": "sc://test:12/", 1041 "host": "test:12", 1042 "hostname": "test", 1043 "port": "12" 1044 } 1045 }, 1046 { 1047 "comment": "Leading / is not stripped", 1048 "href": "http://example.com/", 1049 "new_value": "///bad.com", 1050 "expected": { 1051 "href": "http://example.com/", 1052 "host": "example.com", 1053 "hostname": "example.com" 1054 } 1055 }, 1056 { 1057 "comment": "Leading / is not stripped", 1058 "href": "sc://example.com/", 1059 "new_value": "///bad.com", 1060 "expected": { 1061 "href": "sc:///", 1062 "host": "", 1063 "hostname": "" 1064 } 1065 }, 1066 { 1067 "href": "https://example.com/", 1068 "new_value": "a%C2%ADb", 1069 "expected": { 1070 "href": "https://ab/", 1071 "host": "ab", 1072 "hostname": "ab" 1073 } 1074 }, 1075 { 1076 "href": "https://example.com/", 1077 "new_value": "\u00AD", 1078 "expected": { 1079 "href": "https://example.com/", 1080 "host": "example.com", 1081 "hostname": "example.com" 1082 } 1083 }, 1084 { 1085 "href": "https://example.com/", 1086 "new_value": "%C2%AD", 1087 "expected": { 1088 "href": "https://example.com/", 1089 "host": "example.com", 1090 "hostname": "example.com" 1091 } 1092 }, 1093 { 1094 "href": "https://example.com/", 1095 "new_value": "xn--", 1096 "expected": { 1097 "href": "https://example.com/", 1098 "host": "example.com", 1099 "hostname": "example.com" 1100 } 1101 } 1102 ], 1103 "hostname": [ 1104 { 1105 "comment": "Non-special scheme", 1106 "href": "sc://x/", 1107 "new_value": "\u0000", 1108 "expected": { 1109 "href": "sc://x/", 1110 "host": "x", 1111 "hostname": "x" 1112 } 1113 }, 1114 { 1115 "href": "sc://x/", 1116 "new_value": "\u0009", 1117 "expected": { 1118 "href": "sc:///", 1119 "host": "", 1120 "hostname": "" 1121 } 1122 }, 1123 { 1124 "href": "sc://x/", 1125 "new_value": "\u000A", 1126 "expected": { 1127 "href": "sc:///", 1128 "host": "", 1129 "hostname": "" 1130 } 1131 }, 1132 { 1133 "href": "sc://x/", 1134 "new_value": "\u000D", 1135 "expected": { 1136 "href": "sc:///", 1137 "host": "", 1138 "hostname": "" 1139 } 1140 }, 1141 { 1142 "href": "sc://x/", 1143 "new_value": " ", 1144 "expected": { 1145 "href": "sc://x/", 1146 "host": "x", 1147 "hostname": "x" 1148 } 1149 }, 1150 { 1151 "href": "sc://x/", 1152 "new_value": "#", 1153 "expected": { 1154 "href": "sc:///", 1155 "host": "", 1156 "hostname": "" 1157 } 1158 }, 1159 { 1160 "href": "sc://x/", 1161 "new_value": "/", 1162 "expected": { 1163 "href": "sc:///", 1164 "host": "", 1165 "hostname": "" 1166 } 1167 }, 1168 { 1169 "href": "sc://x/", 1170 "new_value": "?", 1171 "expected": { 1172 "href": "sc:///", 1173 "host": "", 1174 "hostname": "" 1175 } 1176 }, 1177 { 1178 "href": "sc://x/", 1179 "new_value": "@", 1180 "expected": { 1181 "href": "sc://x/", 1182 "host": "x", 1183 "hostname": "x" 1184 } 1185 }, 1186 { 1187 "comment": "Cannot-be-a-base means no host", 1188 "href": "mailto:me@example.net", 1189 "new_value": "example.com", 1190 "expected": { 1191 "href": "mailto:me@example.net", 1192 "host": "" 1193 } 1194 }, 1195 { 1196 "comment": "Cannot-be-a-base means no host", 1197 "href": "data:text/plain,Stuff", 1198 "new_value": "example.net", 1199 "expected": { 1200 "href": "data:text/plain,Stuff", 1201 "host": "" 1202 } 1203 }, 1204 { 1205 "href": "http://example.net:8080", 1206 "new_value": "example.com", 1207 "expected": { 1208 "href": "http://example.com:8080/", 1209 "host": "example.com:8080", 1210 "hostname": "example.com", 1211 "port": "8080" 1212 } 1213 }, 1214 { 1215 "comment": "The empty host is not valid for special schemes", 1216 "href": "http://example.net", 1217 "new_value": "", 1218 "expected": { 1219 "href": "http://example.net/", 1220 "host": "example.net" 1221 } 1222 }, 1223 { 1224 "comment": "The empty host is OK for non-special schemes", 1225 "href": "view-source+http://example.net/foo", 1226 "new_value": "", 1227 "expected": { 1228 "href": "view-source+http:///foo", 1229 "host": "" 1230 } 1231 }, 1232 { 1233 "comment": "Path-only URLs can gain a host", 1234 "href": "a:/foo", 1235 "new_value": "example.net", 1236 "expected": { 1237 "href": "a://example.net/foo", 1238 "host": "example.net" 1239 } 1240 }, 1241 { 1242 "comment": "IPv4 address syntax is normalized", 1243 "href": "http://example.net:8080", 1244 "new_value": "0x7F000001", 1245 "expected": { 1246 "href": "http://127.0.0.1:8080/", 1247 "host": "127.0.0.1:8080", 1248 "hostname": "127.0.0.1", 1249 "port": "8080" 1250 } 1251 }, 1252 { 1253 "comment": "IPv6 address syntax is normalized", 1254 "href": "http://example.net", 1255 "new_value": "[::0:01]", 1256 "expected": { 1257 "href": "http://[::1]/", 1258 "host": "[::1]", 1259 "hostname": "[::1]", 1260 "port": "" 1261 } 1262 }, 1263 { 1264 "comment": ": delimiter invalidates entire value", 1265 "href": "http://example.net/path", 1266 "new_value": "example.com:8080", 1267 "expected": { 1268 "href": "http://example.net/path", 1269 "host": "example.net", 1270 "hostname": "example.net", 1271 "port": "" 1272 } 1273 }, 1274 { 1275 "comment": ": delimiter invalidates entire value", 1276 "href": "http://example.net:8080/path", 1277 "new_value": "example.com:", 1278 "expected": { 1279 "href": "http://example.net:8080/path", 1280 "host": "example.net:8080", 1281 "hostname": "example.net", 1282 "port": "8080" 1283 } 1284 }, 1285 { 1286 "comment": "Stuff after a / delimiter is ignored", 1287 "href": "http://example.net/path", 1288 "new_value": "example.com/stuff", 1289 "expected": { 1290 "href": "http://example.com/path", 1291 "host": "example.com", 1292 "hostname": "example.com", 1293 "port": "" 1294 } 1295 }, 1296 { 1297 "comment": "Stuff after a ? delimiter is ignored", 1298 "href": "http://example.net/path", 1299 "new_value": "example.com?stuff", 1300 "expected": { 1301 "href": "http://example.com/path", 1302 "host": "example.com", 1303 "hostname": "example.com", 1304 "port": "" 1305 } 1306 }, 1307 { 1308 "comment": "Stuff after a # delimiter is ignored", 1309 "href": "http://example.net/path", 1310 "new_value": "example.com#stuff", 1311 "expected": { 1312 "href": "http://example.com/path", 1313 "host": "example.com", 1314 "hostname": "example.com", 1315 "port": "" 1316 } 1317 }, 1318 { 1319 "comment": "Stuff after a \\ delimiter is ignored for special schemes", 1320 "href": "http://example.net/path", 1321 "new_value": "example.com\\stuff", 1322 "expected": { 1323 "href": "http://example.com/path", 1324 "host": "example.com", 1325 "hostname": "example.com", 1326 "port": "" 1327 } 1328 }, 1329 { 1330 "comment": "\\ is not a delimiter for non-special schemes, but still forbidden in hosts", 1331 "href": "view-source+http://example.net/path", 1332 "new_value": "example.com\\stuff", 1333 "expected": { 1334 "href": "view-source+http://example.net/path", 1335 "host": "example.net", 1336 "hostname": "example.net", 1337 "port": "" 1338 } 1339 }, 1340 { 1341 "comment": "Broken IPv6", 1342 "href": "http://example.net/", 1343 "new_value": "[google.com]", 1344 "expected": { 1345 "href": "http://example.net/", 1346 "host": "example.net", 1347 "hostname": "example.net" 1348 } 1349 }, 1350 { 1351 "href": "http://example.net/", 1352 "new_value": "[::1.2.3.4x]", 1353 "expected": { 1354 "href": "http://example.net/", 1355 "host": "example.net", 1356 "hostname": "example.net" 1357 } 1358 }, 1359 { 1360 "href": "http://example.net/", 1361 "new_value": "[::1.2.3.]", 1362 "expected": { 1363 "href": "http://example.net/", 1364 "host": "example.net", 1365 "hostname": "example.net" 1366 } 1367 }, 1368 { 1369 "href": "http://example.net/", 1370 "new_value": "[::1.2.]", 1371 "expected": { 1372 "href": "http://example.net/", 1373 "host": "example.net", 1374 "hostname": "example.net" 1375 } 1376 }, 1377 { 1378 "href": "http://example.net/", 1379 "new_value": "[::1.]", 1380 "expected": { 1381 "href": "http://example.net/", 1382 "host": "example.net", 1383 "hostname": "example.net" 1384 } 1385 }, 1386 { 1387 "href": "file://y/", 1388 "new_value": "x:123", 1389 "expected": { 1390 "href": "file://y/", 1391 "host": "y", 1392 "hostname": "y", 1393 "port": "" 1394 } 1395 }, 1396 { 1397 "href": "file://y/", 1398 "new_value": "loc%41lhost", 1399 "expected": { 1400 "href": "file:///", 1401 "host": "", 1402 "hostname": "", 1403 "port": "" 1404 } 1405 }, 1406 { 1407 "href": "file://hi/x", 1408 "new_value": "", 1409 "expected": { 1410 "href": "file:///x", 1411 "host": "", 1412 "hostname": "", 1413 "port": "" 1414 } 1415 }, 1416 { 1417 "href": "sc://test@test/", 1418 "new_value": "", 1419 "expected": { 1420 "href": "sc://test@test/", 1421 "host": "test", 1422 "hostname": "test", 1423 "username": "test" 1424 } 1425 }, 1426 { 1427 "href": "sc://test:12/", 1428 "new_value": "", 1429 "expected": { 1430 "href": "sc://test:12/", 1431 "host": "test:12", 1432 "hostname": "test", 1433 "port": "12" 1434 } 1435 }, 1436 { 1437 "comment": "Drop /. from path", 1438 "href": "non-spec:/.//p", 1439 "new_value": "h", 1440 "expected": { 1441 "href": "non-spec://h//p", 1442 "host": "h", 1443 "hostname": "h", 1444 "pathname": "//p" 1445 } 1446 }, 1447 { 1448 "href": "non-spec:/.//p", 1449 "new_value": "", 1450 "expected": { 1451 "href": "non-spec:////p", 1452 "host": "", 1453 "hostname": "", 1454 "pathname": "//p" 1455 } 1456 }, 1457 { 1458 "comment": "Leading / is not stripped", 1459 "href": "http://example.com/", 1460 "new_value": "///bad.com", 1461 "expected": { 1462 "href": "http://example.com/", 1463 "host": "example.com", 1464 "hostname": "example.com" 1465 } 1466 }, 1467 { 1468 "comment": "Leading / is not stripped", 1469 "href": "sc://example.com/", 1470 "new_value": "///bad.com", 1471 "expected": { 1472 "href": "sc:///", 1473 "host": "", 1474 "hostname": "" 1475 } 1476 }, 1477 { 1478 "href": "https://example.com/", 1479 "new_value": "a%C2%ADb", 1480 "expected": { 1481 "href": "https://ab/", 1482 "host": "ab", 1483 "hostname": "ab" 1484 } 1485 }, 1486 { 1487 "href": "https://example.com/", 1488 "new_value": "\u00AD", 1489 "expected": { 1490 "href": "https://example.com/", 1491 "host": "example.com", 1492 "hostname": "example.com" 1493 } 1494 }, 1495 { 1496 "href": "https://example.com/", 1497 "new_value": "%C2%AD", 1498 "expected": { 1499 "href": "https://example.com/", 1500 "host": "example.com", 1501 "hostname": "example.com" 1502 } 1503 }, 1504 { 1505 "href": "https://example.com/", 1506 "new_value": "xn--", 1507 "expected": { 1508 "href": "https://example.com/", 1509 "host": "example.com", 1510 "hostname": "example.com" 1511 } 1512 } 1513 ], 1514 "port": [ 1515 { 1516 "href": "http://example.net", 1517 "new_value": "8080", 1518 "expected": { 1519 "href": "http://example.net:8080/", 1520 "host": "example.net:8080", 1521 "hostname": "example.net", 1522 "port": "8080" 1523 } 1524 }, 1525 { 1526 "comment": "Port number is removed if empty is the new value", 1527 "href": "http://example.net:8080", 1528 "new_value": "", 1529 "expected": { 1530 "href": "http://example.net/", 1531 "host": "example.net", 1532 "hostname": "example.net", 1533 "port": "" 1534 } 1535 }, 1536 { 1537 "comment": "Default port number is removed", 1538 "href": "http://example.net:8080", 1539 "new_value": "80", 1540 "expected": { 1541 "href": "http://example.net/", 1542 "host": "example.net", 1543 "hostname": "example.net", 1544 "port": "" 1545 } 1546 }, 1547 { 1548 "comment": "Default port number is removed", 1549 "href": "https://example.net:4433", 1550 "new_value": "443", 1551 "expected": { 1552 "href": "https://example.net/", 1553 "host": "example.net", 1554 "hostname": "example.net", 1555 "port": "" 1556 } 1557 }, 1558 { 1559 "comment": "Default port number is only removed for the relevant scheme", 1560 "href": "https://example.net", 1561 "new_value": "80", 1562 "expected": { 1563 "href": "https://example.net:80/", 1564 "host": "example.net:80", 1565 "hostname": "example.net", 1566 "port": "80" 1567 } 1568 }, 1569 { 1570 "comment": "Stuff after a / delimiter is ignored", 1571 "href": "http://example.net/path", 1572 "new_value": "8080/stuff", 1573 "expected": { 1574 "href": "http://example.net:8080/path", 1575 "host": "example.net:8080", 1576 "hostname": "example.net", 1577 "port": "8080" 1578 } 1579 }, 1580 { 1581 "comment": "Stuff after a ? delimiter is ignored", 1582 "href": "http://example.net/path", 1583 "new_value": "8080?stuff", 1584 "expected": { 1585 "href": "http://example.net:8080/path", 1586 "host": "example.net:8080", 1587 "hostname": "example.net", 1588 "port": "8080" 1589 } 1590 }, 1591 { 1592 "comment": "Stuff after a # delimiter is ignored", 1593 "href": "http://example.net/path", 1594 "new_value": "8080#stuff", 1595 "expected": { 1596 "href": "http://example.net:8080/path", 1597 "host": "example.net:8080", 1598 "hostname": "example.net", 1599 "port": "8080" 1600 } 1601 }, 1602 { 1603 "comment": "Stuff after a \\ delimiter is ignored for special schemes", 1604 "href": "http://example.net/path", 1605 "new_value": "8080\\stuff", 1606 "expected": { 1607 "href": "http://example.net:8080/path", 1608 "host": "example.net:8080", 1609 "hostname": "example.net", 1610 "port": "8080" 1611 } 1612 }, 1613 { 1614 "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", 1615 "href": "view-source+http://example.net/path", 1616 "new_value": "8080stuff2", 1617 "expected": { 1618 "href": "view-source+http://example.net:8080/path", 1619 "host": "example.net:8080", 1620 "hostname": "example.net", 1621 "port": "8080" 1622 } 1623 }, 1624 { 1625 "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", 1626 "href": "http://example.net/path", 1627 "new_value": "8080stuff2", 1628 "expected": { 1629 "href": "http://example.net:8080/path", 1630 "host": "example.net:8080", 1631 "hostname": "example.net", 1632 "port": "8080" 1633 } 1634 }, 1635 { 1636 "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", 1637 "href": "http://example.net/path", 1638 "new_value": "8080+2", 1639 "expected": { 1640 "href": "http://example.net:8080/path", 1641 "host": "example.net:8080", 1642 "hostname": "example.net", 1643 "port": "8080" 1644 } 1645 }, 1646 { 1647 "comment": "Port numbers are 16 bit integers", 1648 "href": "http://example.net/path", 1649 "new_value": "65535", 1650 "expected": { 1651 "href": "http://example.net:65535/path", 1652 "host": "example.net:65535", 1653 "hostname": "example.net", 1654 "port": "65535" 1655 } 1656 }, 1657 { 1658 "comment": "Port numbers are 16 bit integers, overflowing is an error", 1659 "href": "http://example.net:8080/path", 1660 "new_value": "65536", 1661 "expected": { 1662 "href": "http://example.net:8080/path", 1663 "host": "example.net:8080", 1664 "hostname": "example.net", 1665 "port": "8080" 1666 } 1667 }, 1668 { 1669 "comment": "Setting port to a string that doesn't parse as a number", 1670 "href": "http://example.net:8080/path", 1671 "new_value": "randomstring", 1672 "expected": { 1673 "href": "http://example.net:8080/path", 1674 "host": "example.net:8080", 1675 "hostname": "example.net", 1676 "port": "8080" 1677 } 1678 }, 1679 { 1680 "comment": "Port numbers are 16 bit integers, overflowing is an error", 1681 "href": "non-special://example.net:8080/path", 1682 "new_value": "65536", 1683 "expected": { 1684 "href": "non-special://example.net:8080/path", 1685 "host": "example.net:8080", 1686 "hostname": "example.net", 1687 "port": "8080" 1688 } 1689 }, 1690 { 1691 "href": "file://test/", 1692 "new_value": "12", 1693 "expected": { 1694 "href": "file://test/", 1695 "port": "" 1696 } 1697 }, 1698 { 1699 "href": "file://localhost/", 1700 "new_value": "12", 1701 "expected": { 1702 "href": "file:///", 1703 "port": "" 1704 } 1705 }, 1706 { 1707 "href": "non-base:value", 1708 "new_value": "12", 1709 "expected": { 1710 "href": "non-base:value", 1711 "port": "" 1712 } 1713 }, 1714 { 1715 "href": "sc:///", 1716 "new_value": "12", 1717 "expected": { 1718 "href": "sc:///", 1719 "port": "" 1720 } 1721 }, 1722 { 1723 "href": "sc://x/", 1724 "new_value": "12", 1725 "expected": { 1726 "href": "sc://x:12/", 1727 "port": "12" 1728 } 1729 }, 1730 { 1731 "href": "javascript://x/", 1732 "new_value": "12", 1733 "expected": { 1734 "href": "javascript://x:12/", 1735 "port": "12" 1736 } 1737 }, 1738 { 1739 "comment": "Leading u0009 on special scheme", 1740 "href": "https://domain.com:443", 1741 "new_value": "\u00098080", 1742 "expected": { 1743 "port": "8080" 1744 } 1745 }, 1746 { 1747 "comment": "Leading u0009 on non-special scheme", 1748 "href": "wpt++://domain.com:443", 1749 "new_value": "\u00098080", 1750 "expected": { 1751 "port": "8080" 1752 } 1753 }, 1754 { 1755 "comment": "Should use all ascii prefixed characters as port", 1756 "href": "https://www.google.com:4343", 1757 "new_value": "4wpt", 1758 "expected": { 1759 "port": "4" 1760 } 1761 } 1762 ], 1763 "pathname": [ 1764 { 1765 "comment": "Opaque paths cannot be set", 1766 "href": "mailto:me@example.net", 1767 "new_value": "/foo", 1768 "expected": { 1769 "href": "mailto:me@example.net", 1770 "pathname": "me@example.net" 1771 } 1772 }, 1773 { 1774 "href": "data:original", 1775 "new_value": "new value", 1776 "expected": { 1777 "href": "data:original", 1778 "pathname": "original" 1779 } 1780 }, 1781 { 1782 "href": "sc:original", 1783 "new_value": "new value", 1784 "expected": { 1785 "href": "sc:original", 1786 "pathname": "original" 1787 } 1788 }, 1789 { 1790 "comment": "Special URLs cannot have their paths erased", 1791 "href": "file:///some/path", 1792 "new_value": "", 1793 "expected": { 1794 "href": "file:///", 1795 "pathname": "/" 1796 } 1797 }, 1798 { 1799 "comment": "Non-special URLs can have their paths erased", 1800 "href": "foo://somehost/some/path", 1801 "new_value": "", 1802 "expected": { 1803 "href": "foo://somehost", 1804 "pathname": "" 1805 } 1806 }, 1807 { 1808 "comment": "Non-special URLs with an empty host can have their paths erased", 1809 "href": "foo:///some/path", 1810 "new_value": "", 1811 "expected": { 1812 "href": "foo://", 1813 "pathname": "" 1814 } 1815 }, 1816 { 1817 "comment": "Path-only URLs cannot have their paths erased", 1818 "href": "foo:/some/path", 1819 "new_value": "", 1820 "expected": { 1821 "href": "foo:/", 1822 "pathname": "/" 1823 } 1824 }, 1825 { 1826 "comment": "Path-only URLs always have an initial slash", 1827 "href": "foo:/some/path", 1828 "new_value": "test", 1829 "expected": { 1830 "href": "foo:/test", 1831 "pathname": "/test" 1832 } 1833 }, 1834 { 1835 "href": "unix:/run/foo.socket?timeout=10", 1836 "new_value": "/var/log/../run/bar.socket", 1837 "expected": { 1838 "href": "unix:/var/run/bar.socket?timeout=10", 1839 "pathname": "/var/run/bar.socket" 1840 } 1841 }, 1842 { 1843 "href": "https://example.net#nav", 1844 "new_value": "home", 1845 "expected": { 1846 "href": "https://example.net/home#nav", 1847 "pathname": "/home" 1848 } 1849 }, 1850 { 1851 "href": "https://example.net#nav", 1852 "new_value": "../home", 1853 "expected": { 1854 "href": "https://example.net/home#nav", 1855 "pathname": "/home" 1856 } 1857 }, 1858 { 1859 "comment": "\\ is a segment delimiter for 'special' URLs", 1860 "href": "http://example.net/home?lang=fr#nav", 1861 "new_value": "\\a\\%2E\\b\\%2e.\\c", 1862 "expected": { 1863 "href": "http://example.net/a/c?lang=fr#nav", 1864 "pathname": "/a/c" 1865 } 1866 }, 1867 { 1868 "comment": "\\ is *not* a segment delimiter for non-'special' URLs", 1869 "href": "view-source+http://example.net/home?lang=fr#nav", 1870 "new_value": "\\a\\%2E\\b\\%2e.\\c", 1871 "expected": { 1872 "href": "view-source+http://example.net/\\a\\%2E\\b\\%2e.\\c?lang=fr#nav", 1873 "pathname": "/\\a\\%2E\\b\\%2e.\\c" 1874 } 1875 }, 1876 { 1877 "comment": "UTF-8 percent encoding with the default encode set. Tabs and newlines are removed.", 1878 "href": "a:/", 1879 "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé", 1880 "expected": { 1881 "href": "a:/%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E%3F@AZ[\\]^_%60az%7B|%7D~%7F%C2%80%C2%81%C3%89%C3%A9", 1882 "pathname": "/%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E%3F@AZ[\\]^_%60az%7B|%7D~%7F%C2%80%C2%81%C3%89%C3%A9" 1883 } 1884 }, 1885 { 1886 "comment": "Bytes already percent-encoded are left as-is, including %2E outside dotted segments.", 1887 "href": "http://example.net", 1888 "new_value": "%2e%2E%c3%89té", 1889 "expected": { 1890 "href": "http://example.net/%2e%2E%c3%89t%C3%A9", 1891 "pathname": "/%2e%2E%c3%89t%C3%A9" 1892 } 1893 }, 1894 { 1895 "comment": "? needs to be encoded", 1896 "href": "http://example.net", 1897 "new_value": "?", 1898 "expected": { 1899 "href": "http://example.net/%3F", 1900 "pathname": "/%3F" 1901 } 1902 }, 1903 { 1904 "comment": "# needs to be encoded", 1905 "href": "http://example.net", 1906 "new_value": "#", 1907 "expected": { 1908 "href": "http://example.net/%23", 1909 "pathname": "/%23" 1910 } 1911 }, 1912 { 1913 "comment": "? needs to be encoded, non-special scheme", 1914 "href": "sc://example.net", 1915 "new_value": "?", 1916 "expected": { 1917 "href": "sc://example.net/%3F", 1918 "pathname": "/%3F" 1919 } 1920 }, 1921 { 1922 "comment": "# needs to be encoded, non-special scheme", 1923 "href": "sc://example.net", 1924 "new_value": "#", 1925 "expected": { 1926 "href": "sc://example.net/%23", 1927 "pathname": "/%23" 1928 } 1929 }, 1930 { 1931 "comment": "? doesn't mess up encoding", 1932 "href": "http://example.net", 1933 "new_value": "/?é", 1934 "expected": { 1935 "href": "http://example.net/%3F%C3%A9", 1936 "pathname": "/%3F%C3%A9" 1937 } 1938 }, 1939 { 1940 "comment": "# doesn't mess up encoding", 1941 "href": "http://example.net", 1942 "new_value": "/#é", 1943 "expected": { 1944 "href": "http://example.net/%23%C3%A9", 1945 "pathname": "/%23%C3%A9" 1946 } 1947 }, 1948 { 1949 "comment": "File URLs and (back)slashes", 1950 "href": "file://monkey/", 1951 "new_value": "\\\\", 1952 "expected": { 1953 "href": "file://monkey//", 1954 "pathname": "//" 1955 } 1956 }, 1957 { 1958 "comment": "File URLs and (back)slashes", 1959 "href": "file:///unicorn", 1960 "new_value": "//\\/", 1961 "expected": { 1962 "href": "file://////", 1963 "pathname": "////" 1964 } 1965 }, 1966 { 1967 "comment": "File URLs and (back)slashes", 1968 "href": "file:///unicorn", 1969 "new_value": "//monkey/..//", 1970 "expected": { 1971 "href": "file://///", 1972 "pathname": "///" 1973 } 1974 }, 1975 { 1976 "comment": "Serialize /. in path", 1977 "href": "non-spec:/", 1978 "new_value": "/.//p", 1979 "expected": { 1980 "href": "non-spec:/.//p", 1981 "pathname": "//p" 1982 } 1983 }, 1984 { 1985 "href": "non-spec:/", 1986 "new_value": "/..//p", 1987 "expected": { 1988 "href": "non-spec:/.//p", 1989 "pathname": "//p" 1990 } 1991 }, 1992 { 1993 "href": "non-spec:/", 1994 "new_value": "//p", 1995 "expected": { 1996 "href": "non-spec:/.//p", 1997 "pathname": "//p" 1998 } 1999 }, 2000 { 2001 "comment": "Drop /. from path", 2002 "href": "non-spec:/.//", 2003 "new_value": "p", 2004 "expected": { 2005 "href": "non-spec:/p", 2006 "pathname": "/p" 2007 } 2008 }, 2009 { 2010 "comment": "Non-special URLs with non-opaque paths percent-encode U+0020", 2011 "href": "data:/nospace", 2012 "new_value": "space ", 2013 "expected": { 2014 "href": "data:/space%20", 2015 "pathname": "/space%20" 2016 } 2017 }, 2018 { 2019 "href": "sc:/nospace", 2020 "new_value": "space ", 2021 "expected": { 2022 "href": "sc:/space%20", 2023 "pathname": "/space%20" 2024 } 2025 }, 2026 { 2027 "comment": "Trailing space should be encoded", 2028 "href": "http://example.net", 2029 "new_value": " ", 2030 "expected": { 2031 "href": "http://example.net/%20", 2032 "pathname": "/%20" 2033 } 2034 }, 2035 { 2036 "comment": "Trailing C0 control should be encoded", 2037 "href": "http://example.net", 2038 "new_value": "\u0000", 2039 "expected": { 2040 "href": "http://example.net/%00", 2041 "pathname": "/%00" 2042 } 2043 } 2044 ], 2045 "search": [ 2046 { 2047 "href": "https://example.net#nav", 2048 "new_value": "lang=fr", 2049 "expected": { 2050 "href": "https://example.net/?lang=fr#nav", 2051 "search": "?lang=fr" 2052 } 2053 }, 2054 { 2055 "href": "https://example.net?lang=en-US#nav", 2056 "new_value": "lang=fr", 2057 "expected": { 2058 "href": "https://example.net/?lang=fr#nav", 2059 "search": "?lang=fr" 2060 } 2061 }, 2062 { 2063 "href": "https://example.net?lang=en-US#nav", 2064 "new_value": "?lang=fr", 2065 "expected": { 2066 "href": "https://example.net/?lang=fr#nav", 2067 "search": "?lang=fr" 2068 } 2069 }, 2070 { 2071 "href": "https://example.net?lang=en-US#nav", 2072 "new_value": "??lang=fr", 2073 "expected": { 2074 "href": "https://example.net/??lang=fr#nav", 2075 "search": "??lang=fr" 2076 } 2077 }, 2078 { 2079 "href": "https://example.net?lang=en-US#nav", 2080 "new_value": "?", 2081 "expected": { 2082 "href": "https://example.net/?#nav", 2083 "search": "" 2084 } 2085 }, 2086 { 2087 "href": "https://example.net?lang=en-US#nav", 2088 "new_value": "", 2089 "expected": { 2090 "href": "https://example.net/#nav", 2091 "search": "" 2092 } 2093 }, 2094 { 2095 "href": "https://example.net?lang=en-US", 2096 "new_value": "", 2097 "expected": { 2098 "href": "https://example.net/", 2099 "search": "" 2100 } 2101 }, 2102 { 2103 "href": "https://example.net", 2104 "new_value": "", 2105 "expected": { 2106 "href": "https://example.net/", 2107 "search": "" 2108 } 2109 }, 2110 { 2111 "comment": "UTF-8 percent encoding with the query encode set. Tabs and newlines are removed.", 2112 "href": "a:/", 2113 "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé", 2114 "expected": { 2115 "href": "a:/?%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_`az{|}~%7F%C2%80%C2%81%C3%89%C3%A9", 2116 "search": "?%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_`az{|}~%7F%C2%80%C2%81%C3%89%C3%A9" 2117 } 2118 }, 2119 { 2120 "comment": "Bytes already percent-encoded are left as-is", 2121 "href": "http://example.net", 2122 "new_value": "%c3%89té", 2123 "expected": { 2124 "href": "http://example.net/?%c3%89t%C3%A9", 2125 "search": "?%c3%89t%C3%A9" 2126 } 2127 }, 2128 { 2129 "comment": "Drop trailing spaces from trailing opaque paths", 2130 "href": "data:space ?query", 2131 "new_value": "", 2132 "expected": { 2133 "href": "data:space", 2134 "pathname": "space", 2135 "search": "" 2136 } 2137 }, 2138 { 2139 "href": "sc:space ?query", 2140 "new_value": "", 2141 "expected": { 2142 "href": "sc:space", 2143 "pathname": "space", 2144 "search": "" 2145 } 2146 }, 2147 { 2148 "comment": "Do not drop trailing spaces from non-trailing opaque paths", 2149 "href": "data:space ?query#fragment", 2150 "new_value": "", 2151 "expected": { 2152 "href": "data:space #fragment", 2153 "search": "" 2154 } 2155 }, 2156 { 2157 "href": "sc:space ?query#fragment", 2158 "new_value": "", 2159 "expected": { 2160 "href": "sc:space #fragment", 2161 "search": "" 2162 } 2163 }, 2164 { 2165 "comment": "Trailing space should be encoded", 2166 "href": "http://example.net", 2167 "new_value": " ", 2168 "expected": { 2169 "href": "http://example.net/?%20", 2170 "search": "?%20" 2171 } 2172 }, 2173 { 2174 "comment": "Trailing C0 control should be encoded", 2175 "href": "http://example.net", 2176 "new_value": "\u0000", 2177 "expected": { 2178 "href": "http://example.net/?%00", 2179 "search": "?%00" 2180 } 2181 } 2182 ], 2183 "hash": [ 2184 { 2185 "href": "https://example.net", 2186 "new_value": "main", 2187 "expected": { 2188 "href": "https://example.net/#main", 2189 "hash": "#main" 2190 } 2191 }, 2192 { 2193 "href": "https://example.net#nav", 2194 "new_value": "main", 2195 "expected": { 2196 "href": "https://example.net/#main", 2197 "hash": "#main" 2198 } 2199 }, 2200 { 2201 "href": "https://example.net?lang=en-US", 2202 "new_value": "##nav", 2203 "expected": { 2204 "href": "https://example.net/?lang=en-US##nav", 2205 "hash": "##nav" 2206 } 2207 }, 2208 { 2209 "href": "https://example.net?lang=en-US#nav", 2210 "new_value": "#main", 2211 "expected": { 2212 "href": "https://example.net/?lang=en-US#main", 2213 "hash": "#main" 2214 } 2215 }, 2216 { 2217 "href": "https://example.net?lang=en-US#nav", 2218 "new_value": "#", 2219 "expected": { 2220 "href": "https://example.net/?lang=en-US#", 2221 "hash": "" 2222 } 2223 }, 2224 { 2225 "href": "https://example.net?lang=en-US#nav", 2226 "new_value": "", 2227 "expected": { 2228 "href": "https://example.net/?lang=en-US", 2229 "hash": "" 2230 } 2231 }, 2232 { 2233 "href": "http://example.net", 2234 "new_value": "#foo bar", 2235 "expected": { 2236 "href": "http://example.net/#foo%20bar", 2237 "hash": "#foo%20bar" 2238 } 2239 }, 2240 { 2241 "href": "http://example.net", 2242 "new_value": "#foo\"bar", 2243 "expected": { 2244 "href": "http://example.net/#foo%22bar", 2245 "hash": "#foo%22bar" 2246 } 2247 }, 2248 { 2249 "href": "http://example.net", 2250 "new_value": "#foo<bar", 2251 "expected": { 2252 "href": "http://example.net/#foo%3Cbar", 2253 "hash": "#foo%3Cbar" 2254 } 2255 }, 2256 { 2257 "href": "http://example.net", 2258 "new_value": "#foo>bar", 2259 "expected": { 2260 "href": "http://example.net/#foo%3Ebar", 2261 "hash": "#foo%3Ebar" 2262 } 2263 }, 2264 { 2265 "href": "http://example.net", 2266 "new_value": "#foo`bar", 2267 "expected": { 2268 "href": "http://example.net/#foo%60bar", 2269 "hash": "#foo%60bar" 2270 } 2271 }, 2272 { 2273 "comment": "Simple percent-encoding; tabs and newlines are removed", 2274 "href": "a:/", 2275 "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé", 2276 "expected": { 2277 "href": "a:/#%00%01%1F%20!%22#$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9", 2278 "hash": "#%00%01%1F%20!%22#$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9" 2279 } 2280 }, 2281 { 2282 "comment": "Percent-encode NULLs in fragment", 2283 "href": "http://example.net", 2284 "new_value": "a\u0000b", 2285 "expected": { 2286 "href": "http://example.net/#a%00b", 2287 "hash": "#a%00b" 2288 } 2289 }, 2290 { 2291 "comment": "Percent-encode NULLs in fragment", 2292 "href": "non-spec:/", 2293 "new_value": "a\u0000b", 2294 "expected": { 2295 "href": "non-spec:/#a%00b", 2296 "hash": "#a%00b" 2297 } 2298 }, 2299 { 2300 "comment": "Bytes already percent-encoded are left as-is", 2301 "href": "http://example.net", 2302 "new_value": "%c3%89té", 2303 "expected": { 2304 "href": "http://example.net/#%c3%89t%C3%A9", 2305 "hash": "#%c3%89t%C3%A9" 2306 } 2307 }, 2308 { 2309 "href": "javascript:alert(1)", 2310 "new_value": "castle", 2311 "expected": { 2312 "href": "javascript:alert(1)#castle", 2313 "hash": "#castle" 2314 } 2315 }, 2316 { 2317 "comment": "Drop trailing spaces from trailing opaque paths", 2318 "href": "data:space #fragment", 2319 "new_value": "", 2320 "expected": { 2321 "href": "data:space", 2322 "pathname": "space", 2323 "hash": "" 2324 } 2325 }, 2326 { 2327 "href": "sc:space #fragment", 2328 "new_value": "", 2329 "expected": { 2330 "href": "sc:space", 2331 "pathname": "space", 2332 "hash": "" 2333 } 2334 }, 2335 { 2336 "comment": "Do not drop trailing spaces from non-trailing opaque paths", 2337 "href": "data:space ?query#fragment", 2338 "new_value": "", 2339 "expected": { 2340 "href": "data:space ?query", 2341 "hash": "" 2342 } 2343 }, 2344 { 2345 "href": "sc:space ?query#fragment", 2346 "new_value": "", 2347 "expected": { 2348 "href": "sc:space ?query", 2349 "hash": "" 2350 } 2351 }, 2352 { 2353 "comment": "Trailing space should be encoded", 2354 "href": "http://example.net", 2355 "new_value": " ", 2356 "expected": { 2357 "href": "http://example.net/#%20", 2358 "hash": "#%20" 2359 } 2360 }, 2361 { 2362 "comment": "Trailing C0 control should be encoded", 2363 "href": "http://example.net", 2364 "new_value": "\u0000", 2365 "expected": { 2366 "href": "http://example.net/#%00", 2367 "hash": "#%00" 2368 } 2369 } 2370 ], 2371 "href": [ 2372 { 2373 "href": "file:///var/log/system.log", 2374 "new_value": "http://0300.168.0xF0", 2375 "expected": { 2376 "href": "http://192.168.0.240/", 2377 "protocol": "http:" 2378 } 2379 } 2380 ] 2381} 2382