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