1{ 2 "comment": [ 3 "AS OF https://github.com/jsdom/whatwg-url/commit/35f04dfd3048cf6362f4398745bb13375c5020c2", 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": "gopher://example.net:1234", 124 "new_value": "file", 125 "expected": { 126 "href": "gopher://example.net:1234", 127 "protocol": "gopher:" 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": "gopher", 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 "username": [ 276 { 277 "comment": "No host means no username", 278 "href": "file:///home/you/index.html", 279 "new_value": "me", 280 "expected": { 281 "href": "file:///home/you/index.html", 282 "username": "" 283 } 284 }, 285 { 286 "comment": "No host means no username", 287 "href": "unix:/run/foo.socket", 288 "new_value": "me", 289 "expected": { 290 "href": "unix:/run/foo.socket", 291 "username": "" 292 } 293 }, 294 { 295 "comment": "Cannot-be-a-base means no username", 296 "href": "mailto:you@example.net", 297 "new_value": "me", 298 "expected": { 299 "href": "mailto:you@example.net", 300 "username": "" 301 } 302 }, 303 { 304 "href": "javascript:alert(1)", 305 "new_value": "wario", 306 "expected": { 307 "href": "javascript:alert(1)", 308 "username": "" 309 } 310 }, 311 { 312 "href": "http://example.net", 313 "new_value": "me", 314 "expected": { 315 "href": "http://me@example.net/", 316 "username": "me" 317 } 318 }, 319 { 320 "href": "http://:secret@example.net", 321 "new_value": "me", 322 "expected": { 323 "href": "http://me:secret@example.net/", 324 "username": "me" 325 } 326 }, 327 { 328 "href": "http://me@example.net", 329 "new_value": "", 330 "expected": { 331 "href": "http://example.net/", 332 "username": "" 333 } 334 }, 335 { 336 "href": "http://me:secret@example.net", 337 "new_value": "", 338 "expected": { 339 "href": "http://:secret@example.net/", 340 "username": "" 341 } 342 }, 343 { 344 "comment": "UTF-8 percent encoding with the userinfo encode set.", 345 "href": "http://example.net", 346 "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé", 347 "expected": { 348 "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/", 349 "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" 350 } 351 }, 352 { 353 "comment": "Bytes already percent-encoded are left as-is.", 354 "href": "http://example.net", 355 "new_value": "%c3%89té", 356 "expected": { 357 "href": "http://%c3%89t%C3%A9@example.net/", 358 "username": "%c3%89t%C3%A9" 359 } 360 }, 361 { 362 "href": "sc:///", 363 "new_value": "x", 364 "expected": { 365 "href": "sc:///", 366 "username": "" 367 } 368 }, 369 { 370 "href": "javascript://x/", 371 "new_value": "wario", 372 "expected": { 373 "href": "javascript://wario@x/", 374 "username": "wario" 375 } 376 }, 377 { 378 "href": "file://test/", 379 "new_value": "test", 380 "expected": { 381 "href": "file://test/", 382 "username": "" 383 } 384 } 385 ], 386 "password": [ 387 { 388 "comment": "No host means no password", 389 "href": "file:///home/me/index.html", 390 "new_value": "secret", 391 "expected": { 392 "href": "file:///home/me/index.html", 393 "password": "" 394 } 395 }, 396 { 397 "comment": "No host means no password", 398 "href": "unix:/run/foo.socket", 399 "new_value": "secret", 400 "expected": { 401 "href": "unix:/run/foo.socket", 402 "password": "" 403 } 404 }, 405 { 406 "comment": "Cannot-be-a-base means no password", 407 "href": "mailto:me@example.net", 408 "new_value": "secret", 409 "expected": { 410 "href": "mailto:me@example.net", 411 "password": "" 412 } 413 }, 414 { 415 "href": "http://example.net", 416 "new_value": "secret", 417 "expected": { 418 "href": "http://:secret@example.net/", 419 "password": "secret" 420 } 421 }, 422 { 423 "href": "http://me@example.net", 424 "new_value": "secret", 425 "expected": { 426 "href": "http://me:secret@example.net/", 427 "password": "secret" 428 } 429 }, 430 { 431 "href": "http://:secret@example.net", 432 "new_value": "", 433 "expected": { 434 "href": "http://example.net/", 435 "password": "" 436 } 437 }, 438 { 439 "href": "http://me:secret@example.net", 440 "new_value": "", 441 "expected": { 442 "href": "http://me@example.net/", 443 "password": "" 444 } 445 }, 446 { 447 "comment": "UTF-8 percent encoding with the userinfo encode set.", 448 "href": "http://example.net", 449 "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé", 450 "expected": { 451 "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/", 452 "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" 453 } 454 }, 455 { 456 "comment": "Bytes already percent-encoded are left as-is.", 457 "href": "http://example.net", 458 "new_value": "%c3%89té", 459 "expected": { 460 "href": "http://:%c3%89t%C3%A9@example.net/", 461 "password": "%c3%89t%C3%A9" 462 } 463 }, 464 { 465 "href": "sc:///", 466 "new_value": "x", 467 "expected": { 468 "href": "sc:///", 469 "password": "" 470 } 471 }, 472 { 473 "href": "javascript://x/", 474 "new_value": "bowser", 475 "expected": { 476 "href": "javascript://:bowser@x/", 477 "password": "bowser" 478 } 479 }, 480 { 481 "href": "file://test/", 482 "new_value": "test", 483 "expected": { 484 "href": "file://test/", 485 "password": "" 486 } 487 } 488 ], 489 "host": [ 490 { 491 "comment": "Non-special scheme", 492 "href": "sc://x/", 493 "new_value": "\u0000", 494 "expected": { 495 "href": "sc://x/", 496 "host": "x", 497 "hostname": "x" 498 } 499 }, 500 { 501 "href": "sc://x/", 502 "new_value": "\u0009", 503 "expected": { 504 "href": "sc:///", 505 "host": "", 506 "hostname": "" 507 } 508 }, 509 { 510 "href": "sc://x/", 511 "new_value": "\u000A", 512 "expected": { 513 "href": "sc:///", 514 "host": "", 515 "hostname": "" 516 } 517 }, 518 { 519 "href": "sc://x/", 520 "new_value": "\u000D", 521 "expected": { 522 "href": "sc:///", 523 "host": "", 524 "hostname": "" 525 } 526 }, 527 { 528 "href": "sc://x/", 529 "new_value": " ", 530 "expected": { 531 "href": "sc://x/", 532 "host": "x", 533 "hostname": "x" 534 } 535 }, 536 { 537 "href": "sc://x/", 538 "new_value": "#", 539 "expected": { 540 "href": "sc:///", 541 "host": "", 542 "hostname": "" 543 } 544 }, 545 { 546 "href": "sc://x/", 547 "new_value": "/", 548 "expected": { 549 "href": "sc:///", 550 "host": "", 551 "hostname": "" 552 } 553 }, 554 { 555 "href": "sc://x/", 556 "new_value": "?", 557 "expected": { 558 "href": "sc:///", 559 "host": "", 560 "hostname": "" 561 } 562 }, 563 { 564 "href": "sc://x/", 565 "new_value": "@", 566 "expected": { 567 "href": "sc://x/", 568 "host": "x", 569 "hostname": "x" 570 } 571 }, 572 { 573 "href": "sc://x/", 574 "new_value": "ß", 575 "expected": { 576 "href": "sc://%C3%9F/", 577 "host": "%C3%9F", 578 "hostname": "%C3%9F" 579 } 580 }, 581 { 582 "comment": "IDNA Nontransitional_Processing", 583 "href": "https://x/", 584 "new_value": "ß", 585 "expected": { 586 "href": "https://xn--zca/", 587 "host": "xn--zca", 588 "hostname": "xn--zca" 589 } 590 }, 591 { 592 "comment": "Cannot-be-a-base means no host", 593 "href": "mailto:me@example.net", 594 "new_value": "example.com", 595 "expected": { 596 "href": "mailto:me@example.net", 597 "host": "" 598 } 599 }, 600 { 601 "comment": "Cannot-be-a-base means no host", 602 "href": "data:text/plain,Stuff", 603 "new_value": "example.net", 604 "expected": { 605 "href": "data:text/plain,Stuff", 606 "host": "" 607 } 608 }, 609 { 610 "href": "http://example.net", 611 "new_value": "example.com:8080", 612 "expected": { 613 "href": "http://example.com:8080/", 614 "host": "example.com:8080", 615 "hostname": "example.com", 616 "port": "8080" 617 } 618 }, 619 { 620 "comment": "Port number is unchanged if not specified in the new value", 621 "href": "http://example.net:8080", 622 "new_value": "example.com", 623 "expected": { 624 "href": "http://example.com:8080/", 625 "host": "example.com:8080", 626 "hostname": "example.com", 627 "port": "8080" 628 } 629 }, 630 { 631 "comment": "Port number is unchanged if not specified", 632 "href": "http://example.net:8080", 633 "new_value": "example.com:", 634 "expected": { 635 "href": "http://example.com:8080/", 636 "host": "example.com:8080", 637 "hostname": "example.com", 638 "port": "8080" 639 } 640 }, 641 { 642 "comment": "The empty host is not valid for special schemes", 643 "href": "http://example.net", 644 "new_value": "", 645 "expected": { 646 "href": "http://example.net/", 647 "host": "example.net" 648 } 649 }, 650 { 651 "comment": "The empty host is OK for non-special schemes", 652 "href": "view-source+http://example.net/foo", 653 "new_value": "", 654 "expected": { 655 "href": "view-source+http:///foo", 656 "host": "" 657 } 658 }, 659 { 660 "comment": "Path-only URLs can gain a host", 661 "href": "a:/foo", 662 "new_value": "example.net", 663 "expected": { 664 "href": "a://example.net/foo", 665 "host": "example.net" 666 } 667 }, 668 { 669 "comment": "IPv4 address syntax is normalized", 670 "href": "http://example.net", 671 "new_value": "0x7F000001:8080", 672 "expected": { 673 "href": "http://127.0.0.1:8080/", 674 "host": "127.0.0.1:8080", 675 "hostname": "127.0.0.1", 676 "port": "8080" 677 } 678 }, 679 { 680 "comment": "IPv6 address syntax is normalized", 681 "href": "http://example.net", 682 "new_value": "[::0:01]:2", 683 "expected": { 684 "href": "http://[::1]:2/", 685 "host": "[::1]:2", 686 "hostname": "[::1]", 687 "port": "2" 688 } 689 }, 690 { 691 "comment": "IPv6 literal address with port, crbug.com/1012416", 692 "href": "http://example.net", 693 "new_value": "[2001:db8::2]:4002", 694 "expected": { 695 "href": "http://[2001:db8::2]:4002/", 696 "host": "[2001:db8::2]:4002", 697 "hostname": "[2001:db8::2]", 698 "port": "4002" 699 } 700 }, 701 { 702 "comment": "Default port number is removed", 703 "href": "http://example.net", 704 "new_value": "example.com:80", 705 "expected": { 706 "href": "http://example.com/", 707 "host": "example.com", 708 "hostname": "example.com", 709 "port": "" 710 } 711 }, 712 { 713 "comment": "Default port number is removed", 714 "href": "https://example.net", 715 "new_value": "example.com:443", 716 "expected": { 717 "href": "https://example.com/", 718 "host": "example.com", 719 "hostname": "example.com", 720 "port": "" 721 } 722 }, 723 { 724 "comment": "Default port number is only removed for the relevant scheme", 725 "href": "https://example.net", 726 "new_value": "example.com:80", 727 "expected": { 728 "href": "https://example.com:80/", 729 "host": "example.com:80", 730 "hostname": "example.com", 731 "port": "80" 732 } 733 }, 734 { 735 "comment": "Port number is removed if new port is scheme default and existing URL has a non-default port", 736 "href": "http://example.net:8080", 737 "new_value": "example.com:80", 738 "expected": { 739 "href": "http://example.com/", 740 "host": "example.com", 741 "hostname": "example.com", 742 "port": "" 743 } 744 }, 745 { 746 "comment": "Stuff after a / delimiter is ignored", 747 "href": "http://example.net/path", 748 "new_value": "example.com/stuff", 749 "expected": { 750 "href": "http://example.com/path", 751 "host": "example.com", 752 "hostname": "example.com", 753 "port": "" 754 } 755 }, 756 { 757 "comment": "Stuff after a / delimiter is ignored", 758 "href": "http://example.net/path", 759 "new_value": "example.com:8080/stuff", 760 "expected": { 761 "href": "http://example.com:8080/path", 762 "host": "example.com:8080", 763 "hostname": "example.com", 764 "port": "8080" 765 } 766 }, 767 { 768 "comment": "Stuff after a ? delimiter is ignored", 769 "href": "http://example.net/path", 770 "new_value": "example.com?stuff", 771 "expected": { 772 "href": "http://example.com/path", 773 "host": "example.com", 774 "hostname": "example.com", 775 "port": "" 776 } 777 }, 778 { 779 "comment": "Stuff after a ? delimiter is ignored", 780 "href": "http://example.net/path", 781 "new_value": "example.com:8080?stuff", 782 "expected": { 783 "href": "http://example.com:8080/path", 784 "host": "example.com:8080", 785 "hostname": "example.com", 786 "port": "8080" 787 } 788 }, 789 { 790 "comment": "Stuff after a # delimiter is ignored", 791 "href": "http://example.net/path", 792 "new_value": "example.com#stuff", 793 "expected": { 794 "href": "http://example.com/path", 795 "host": "example.com", 796 "hostname": "example.com", 797 "port": "" 798 } 799 }, 800 { 801 "comment": "Stuff after a # delimiter is ignored", 802 "href": "http://example.net/path", 803 "new_value": "example.com:8080#stuff", 804 "expected": { 805 "href": "http://example.com:8080/path", 806 "host": "example.com:8080", 807 "hostname": "example.com", 808 "port": "8080" 809 } 810 }, 811 { 812 "comment": "Stuff after a \\ delimiter is ignored for special schemes", 813 "href": "http://example.net/path", 814 "new_value": "example.com\\stuff", 815 "expected": { 816 "href": "http://example.com/path", 817 "host": "example.com", 818 "hostname": "example.com", 819 "port": "" 820 } 821 }, 822 { 823 "comment": "Stuff after a \\ delimiter is ignored for special schemes", 824 "href": "http://example.net/path", 825 "new_value": "example.com:8080\\stuff", 826 "expected": { 827 "href": "http://example.com:8080/path", 828 "host": "example.com:8080", 829 "hostname": "example.com", 830 "port": "8080" 831 } 832 }, 833 { 834 "comment": "\\ is not a delimiter for non-special schemes, but still forbidden in hosts", 835 "href": "view-source+http://example.net/path", 836 "new_value": "example.com\\stuff", 837 "expected": { 838 "href": "view-source+http://example.net/path", 839 "host": "example.net", 840 "hostname": "example.net", 841 "port": "" 842 } 843 }, 844 { 845 "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", 846 "href": "view-source+http://example.net/path", 847 "new_value": "example.com:8080stuff2", 848 "expected": { 849 "href": "view-source+http://example.com:8080/path", 850 "host": "example.com:8080", 851 "hostname": "example.com", 852 "port": "8080" 853 } 854 }, 855 { 856 "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", 857 "href": "http://example.net/path", 858 "new_value": "example.com:8080stuff2", 859 "expected": { 860 "href": "http://example.com:8080/path", 861 "host": "example.com:8080", 862 "hostname": "example.com", 863 "port": "8080" 864 } 865 }, 866 { 867 "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", 868 "href": "http://example.net/path", 869 "new_value": "example.com:8080+2", 870 "expected": { 871 "href": "http://example.com:8080/path", 872 "host": "example.com:8080", 873 "hostname": "example.com", 874 "port": "8080" 875 } 876 }, 877 { 878 "comment": "Port numbers are 16 bit integers", 879 "href": "http://example.net/path", 880 "new_value": "example.com:65535", 881 "expected": { 882 "href": "http://example.com:65535/path", 883 "host": "example.com:65535", 884 "hostname": "example.com", 885 "port": "65535" 886 } 887 }, 888 { 889 "comment": "Port numbers are 16 bit integers, overflowing is an error. Hostname is still set, though.", 890 "href": "http://example.net/path", 891 "new_value": "example.com:65536", 892 "expected": { 893 "href": "http://example.com/path", 894 "host": "example.com", 895 "hostname": "example.com", 896 "port": "" 897 } 898 }, 899 { 900 "comment": "Broken IPv6", 901 "href": "http://example.net/", 902 "new_value": "[google.com]", 903 "expected": { 904 "href": "http://example.net/", 905 "host": "example.net", 906 "hostname": "example.net" 907 } 908 }, 909 { 910 "href": "http://example.net/", 911 "new_value": "[::1.2.3.4x]", 912 "expected": { 913 "href": "http://example.net/", 914 "host": "example.net", 915 "hostname": "example.net" 916 } 917 }, 918 { 919 "href": "http://example.net/", 920 "new_value": "[::1.2.3.]", 921 "expected": { 922 "href": "http://example.net/", 923 "host": "example.net", 924 "hostname": "example.net" 925 } 926 }, 927 { 928 "href": "http://example.net/", 929 "new_value": "[::1.2.]", 930 "expected": { 931 "href": "http://example.net/", 932 "host": "example.net", 933 "hostname": "example.net" 934 } 935 }, 936 { 937 "href": "http://example.net/", 938 "new_value": "[::1.]", 939 "expected": { 940 "href": "http://example.net/", 941 "host": "example.net", 942 "hostname": "example.net" 943 } 944 }, 945 { 946 "href": "file://y/", 947 "new_value": "x:123", 948 "expected": { 949 "href": "file://y/", 950 "host": "y", 951 "hostname": "y", 952 "port": "" 953 } 954 }, 955 { 956 "href": "file://y/", 957 "new_value": "loc%41lhost", 958 "expected": { 959 "href": "file:///", 960 "host": "", 961 "hostname": "", 962 "port": "" 963 } 964 }, 965 { 966 "href": "sc://test@test/", 967 "new_value": "", 968 "expected": { 969 "href": "sc://test@test/", 970 "host": "test", 971 "hostname": "test", 972 "username": "test" 973 } 974 }, 975 { 976 "href": "sc://test:12/", 977 "new_value": "", 978 "expected": { 979 "href": "sc://test:12/", 980 "host": "test:12", 981 "hostname": "test", 982 "port": "12" 983 } 984 } 985 ], 986 "hostname": [ 987 { 988 "comment": "Non-special scheme", 989 "href": "sc://x/", 990 "new_value": "\u0000", 991 "expected": { 992 "href": "sc://x/", 993 "host": "x", 994 "hostname": "x" 995 } 996 }, 997 { 998 "href": "sc://x/", 999 "new_value": "\u0009", 1000 "expected": { 1001 "href": "sc:///", 1002 "host": "", 1003 "hostname": "" 1004 } 1005 }, 1006 { 1007 "href": "sc://x/", 1008 "new_value": "\u000A", 1009 "expected": { 1010 "href": "sc:///", 1011 "host": "", 1012 "hostname": "" 1013 } 1014 }, 1015 { 1016 "href": "sc://x/", 1017 "new_value": "\u000D", 1018 "expected": { 1019 "href": "sc:///", 1020 "host": "", 1021 "hostname": "" 1022 } 1023 }, 1024 { 1025 "href": "sc://x/", 1026 "new_value": " ", 1027 "expected": { 1028 "href": "sc://x/", 1029 "host": "x", 1030 "hostname": "x" 1031 } 1032 }, 1033 { 1034 "href": "sc://x/", 1035 "new_value": "#", 1036 "expected": { 1037 "href": "sc:///", 1038 "host": "", 1039 "hostname": "" 1040 } 1041 }, 1042 { 1043 "href": "sc://x/", 1044 "new_value": "/", 1045 "expected": { 1046 "href": "sc:///", 1047 "host": "", 1048 "hostname": "" 1049 } 1050 }, 1051 { 1052 "href": "sc://x/", 1053 "new_value": "?", 1054 "expected": { 1055 "href": "sc:///", 1056 "host": "", 1057 "hostname": "" 1058 } 1059 }, 1060 { 1061 "href": "sc://x/", 1062 "new_value": "@", 1063 "expected": { 1064 "href": "sc://x/", 1065 "host": "x", 1066 "hostname": "x" 1067 } 1068 }, 1069 { 1070 "comment": "Cannot-be-a-base means no host", 1071 "href": "mailto:me@example.net", 1072 "new_value": "example.com", 1073 "expected": { 1074 "href": "mailto:me@example.net", 1075 "host": "" 1076 } 1077 }, 1078 { 1079 "comment": "Cannot-be-a-base means no host", 1080 "href": "data:text/plain,Stuff", 1081 "new_value": "example.net", 1082 "expected": { 1083 "href": "data:text/plain,Stuff", 1084 "host": "" 1085 } 1086 }, 1087 { 1088 "href": "http://example.net:8080", 1089 "new_value": "example.com", 1090 "expected": { 1091 "href": "http://example.com:8080/", 1092 "host": "example.com:8080", 1093 "hostname": "example.com", 1094 "port": "8080" 1095 } 1096 }, 1097 { 1098 "comment": "The empty host is not valid for special schemes", 1099 "href": "http://example.net", 1100 "new_value": "", 1101 "expected": { 1102 "href": "http://example.net/", 1103 "host": "example.net" 1104 } 1105 }, 1106 { 1107 "comment": "The empty host is OK for non-special schemes", 1108 "href": "view-source+http://example.net/foo", 1109 "new_value": "", 1110 "expected": { 1111 "href": "view-source+http:///foo", 1112 "host": "" 1113 } 1114 }, 1115 { 1116 "comment": "Path-only URLs can gain a host", 1117 "href": "a:/foo", 1118 "new_value": "example.net", 1119 "expected": { 1120 "href": "a://example.net/foo", 1121 "host": "example.net" 1122 } 1123 }, 1124 { 1125 "comment": "IPv4 address syntax is normalized", 1126 "href": "http://example.net:8080", 1127 "new_value": "0x7F000001", 1128 "expected": { 1129 "href": "http://127.0.0.1:8080/", 1130 "host": "127.0.0.1:8080", 1131 "hostname": "127.0.0.1", 1132 "port": "8080" 1133 } 1134 }, 1135 { 1136 "comment": "IPv6 address syntax is normalized", 1137 "href": "http://example.net", 1138 "new_value": "[::0:01]", 1139 "expected": { 1140 "href": "http://[::1]/", 1141 "host": "[::1]", 1142 "hostname": "[::1]", 1143 "port": "" 1144 } 1145 }, 1146 { 1147 "comment": "Stuff after a : delimiter is ignored", 1148 "href": "http://example.net/path", 1149 "new_value": "example.com:8080", 1150 "expected": { 1151 "href": "http://example.com/path", 1152 "host": "example.com", 1153 "hostname": "example.com", 1154 "port": "" 1155 } 1156 }, 1157 { 1158 "comment": "Stuff after a : delimiter is ignored", 1159 "href": "http://example.net:8080/path", 1160 "new_value": "example.com:", 1161 "expected": { 1162 "href": "http://example.com:8080/path", 1163 "host": "example.com:8080", 1164 "hostname": "example.com", 1165 "port": "8080" 1166 } 1167 }, 1168 { 1169 "comment": "Stuff after a / delimiter is ignored", 1170 "href": "http://example.net/path", 1171 "new_value": "example.com/stuff", 1172 "expected": { 1173 "href": "http://example.com/path", 1174 "host": "example.com", 1175 "hostname": "example.com", 1176 "port": "" 1177 } 1178 }, 1179 { 1180 "comment": "Stuff after a ? delimiter is ignored", 1181 "href": "http://example.net/path", 1182 "new_value": "example.com?stuff", 1183 "expected": { 1184 "href": "http://example.com/path", 1185 "host": "example.com", 1186 "hostname": "example.com", 1187 "port": "" 1188 } 1189 }, 1190 { 1191 "comment": "Stuff after a # delimiter is ignored", 1192 "href": "http://example.net/path", 1193 "new_value": "example.com#stuff", 1194 "expected": { 1195 "href": "http://example.com/path", 1196 "host": "example.com", 1197 "hostname": "example.com", 1198 "port": "" 1199 } 1200 }, 1201 { 1202 "comment": "Stuff after a \\ delimiter is ignored for special schemes", 1203 "href": "http://example.net/path", 1204 "new_value": "example.com\\stuff", 1205 "expected": { 1206 "href": "http://example.com/path", 1207 "host": "example.com", 1208 "hostname": "example.com", 1209 "port": "" 1210 } 1211 }, 1212 { 1213 "comment": "\\ is not a delimiter for non-special schemes, but still forbidden in hosts", 1214 "href": "view-source+http://example.net/path", 1215 "new_value": "example.com\\stuff", 1216 "expected": { 1217 "href": "view-source+http://example.net/path", 1218 "host": "example.net", 1219 "hostname": "example.net", 1220 "port": "" 1221 } 1222 }, 1223 { 1224 "comment": "Broken IPv6", 1225 "href": "http://example.net/", 1226 "new_value": "[google.com]", 1227 "expected": { 1228 "href": "http://example.net/", 1229 "host": "example.net", 1230 "hostname": "example.net" 1231 } 1232 }, 1233 { 1234 "href": "http://example.net/", 1235 "new_value": "[::1.2.3.4x]", 1236 "expected": { 1237 "href": "http://example.net/", 1238 "host": "example.net", 1239 "hostname": "example.net" 1240 } 1241 }, 1242 { 1243 "href": "http://example.net/", 1244 "new_value": "[::1.2.3.]", 1245 "expected": { 1246 "href": "http://example.net/", 1247 "host": "example.net", 1248 "hostname": "example.net" 1249 } 1250 }, 1251 { 1252 "href": "http://example.net/", 1253 "new_value": "[::1.2.]", 1254 "expected": { 1255 "href": "http://example.net/", 1256 "host": "example.net", 1257 "hostname": "example.net" 1258 } 1259 }, 1260 { 1261 "href": "http://example.net/", 1262 "new_value": "[::1.]", 1263 "expected": { 1264 "href": "http://example.net/", 1265 "host": "example.net", 1266 "hostname": "example.net" 1267 } 1268 }, 1269 { 1270 "href": "file://y/", 1271 "new_value": "x:123", 1272 "expected": { 1273 "href": "file://y/", 1274 "host": "y", 1275 "hostname": "y", 1276 "port": "" 1277 } 1278 }, 1279 { 1280 "href": "file://y/", 1281 "new_value": "loc%41lhost", 1282 "expected": { 1283 "href": "file:///", 1284 "host": "", 1285 "hostname": "", 1286 "port": "" 1287 } 1288 }, 1289 { 1290 "href": "sc://test@test/", 1291 "new_value": "", 1292 "expected": { 1293 "href": "sc://test@test/", 1294 "host": "test", 1295 "hostname": "test", 1296 "username": "test" 1297 } 1298 }, 1299 { 1300 "href": "sc://test:12/", 1301 "new_value": "", 1302 "expected": { 1303 "href": "sc://test:12/", 1304 "host": "test:12", 1305 "hostname": "test", 1306 "port": "12" 1307 } 1308 } 1309 ], 1310 "port": [ 1311 { 1312 "href": "http://example.net", 1313 "new_value": "8080", 1314 "expected": { 1315 "href": "http://example.net:8080/", 1316 "host": "example.net:8080", 1317 "hostname": "example.net", 1318 "port": "8080" 1319 } 1320 }, 1321 { 1322 "comment": "Port number is removed if empty is the new value", 1323 "href": "http://example.net:8080", 1324 "new_value": "", 1325 "expected": { 1326 "href": "http://example.net/", 1327 "host": "example.net", 1328 "hostname": "example.net", 1329 "port": "" 1330 } 1331 }, 1332 { 1333 "comment": "Default port number is removed", 1334 "href": "http://example.net:8080", 1335 "new_value": "80", 1336 "expected": { 1337 "href": "http://example.net/", 1338 "host": "example.net", 1339 "hostname": "example.net", 1340 "port": "" 1341 } 1342 }, 1343 { 1344 "comment": "Default port number is removed", 1345 "href": "https://example.net:4433", 1346 "new_value": "443", 1347 "expected": { 1348 "href": "https://example.net/", 1349 "host": "example.net", 1350 "hostname": "example.net", 1351 "port": "" 1352 } 1353 }, 1354 { 1355 "comment": "Default port number is only removed for the relevant scheme", 1356 "href": "https://example.net", 1357 "new_value": "80", 1358 "expected": { 1359 "href": "https://example.net:80/", 1360 "host": "example.net:80", 1361 "hostname": "example.net", 1362 "port": "80" 1363 } 1364 }, 1365 { 1366 "comment": "Stuff after a / delimiter is ignored", 1367 "href": "http://example.net/path", 1368 "new_value": "8080/stuff", 1369 "expected": { 1370 "href": "http://example.net:8080/path", 1371 "host": "example.net:8080", 1372 "hostname": "example.net", 1373 "port": "8080" 1374 } 1375 }, 1376 { 1377 "comment": "Stuff after a ? delimiter is ignored", 1378 "href": "http://example.net/path", 1379 "new_value": "8080?stuff", 1380 "expected": { 1381 "href": "http://example.net:8080/path", 1382 "host": "example.net:8080", 1383 "hostname": "example.net", 1384 "port": "8080" 1385 } 1386 }, 1387 { 1388 "comment": "Stuff after a # delimiter is ignored", 1389 "href": "http://example.net/path", 1390 "new_value": "8080#stuff", 1391 "expected": { 1392 "href": "http://example.net:8080/path", 1393 "host": "example.net:8080", 1394 "hostname": "example.net", 1395 "port": "8080" 1396 } 1397 }, 1398 { 1399 "comment": "Stuff after a \\ delimiter is ignored for special schemes", 1400 "href": "http://example.net/path", 1401 "new_value": "8080\\stuff", 1402 "expected": { 1403 "href": "http://example.net:8080/path", 1404 "host": "example.net:8080", 1405 "hostname": "example.net", 1406 "port": "8080" 1407 } 1408 }, 1409 { 1410 "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", 1411 "href": "view-source+http://example.net/path", 1412 "new_value": "8080stuff2", 1413 "expected": { 1414 "href": "view-source+http://example.net:8080/path", 1415 "host": "example.net:8080", 1416 "hostname": "example.net", 1417 "port": "8080" 1418 } 1419 }, 1420 { 1421 "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", 1422 "href": "http://example.net/path", 1423 "new_value": "8080stuff2", 1424 "expected": { 1425 "href": "http://example.net:8080/path", 1426 "host": "example.net:8080", 1427 "hostname": "example.net", 1428 "port": "8080" 1429 } 1430 }, 1431 { 1432 "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", 1433 "href": "http://example.net/path", 1434 "new_value": "8080+2", 1435 "expected": { 1436 "href": "http://example.net:8080/path", 1437 "host": "example.net:8080", 1438 "hostname": "example.net", 1439 "port": "8080" 1440 } 1441 }, 1442 { 1443 "comment": "Port numbers are 16 bit integers", 1444 "href": "http://example.net/path", 1445 "new_value": "65535", 1446 "expected": { 1447 "href": "http://example.net:65535/path", 1448 "host": "example.net:65535", 1449 "hostname": "example.net", 1450 "port": "65535" 1451 } 1452 }, 1453 { 1454 "comment": "Port numbers are 16 bit integers, overflowing is an error", 1455 "href": "http://example.net:8080/path", 1456 "new_value": "65536", 1457 "expected": { 1458 "href": "http://example.net:8080/path", 1459 "host": "example.net:8080", 1460 "hostname": "example.net", 1461 "port": "8080" 1462 } 1463 }, 1464 { 1465 "comment": "Port numbers are 16 bit integers, overflowing is an error", 1466 "href": "non-special://example.net:8080/path", 1467 "new_value": "65536", 1468 "expected": { 1469 "href": "non-special://example.net:8080/path", 1470 "host": "example.net:8080", 1471 "hostname": "example.net", 1472 "port": "8080" 1473 } 1474 }, 1475 { 1476 "href": "file://test/", 1477 "new_value": "12", 1478 "expected": { 1479 "href": "file://test/", 1480 "port": "" 1481 } 1482 }, 1483 { 1484 "href": "file://localhost/", 1485 "new_value": "12", 1486 "expected": { 1487 "href": "file:///", 1488 "port": "" 1489 } 1490 }, 1491 { 1492 "href": "non-base:value", 1493 "new_value": "12", 1494 "expected": { 1495 "href": "non-base:value", 1496 "port": "" 1497 } 1498 }, 1499 { 1500 "href": "sc:///", 1501 "new_value": "12", 1502 "expected": { 1503 "href": "sc:///", 1504 "port": "" 1505 } 1506 }, 1507 { 1508 "href": "sc://x/", 1509 "new_value": "12", 1510 "expected": { 1511 "href": "sc://x:12/", 1512 "port": "12" 1513 } 1514 }, 1515 { 1516 "href": "javascript://x/", 1517 "new_value": "12", 1518 "expected": { 1519 "href": "javascript://x:12/", 1520 "port": "12" 1521 } 1522 } 1523 ], 1524 "pathname": [ 1525 { 1526 "comment": "Cannot-be-a-base don’t have a path", 1527 "href": "mailto:me@example.net", 1528 "new_value": "/foo", 1529 "expected": { 1530 "href": "mailto:me@example.net", 1531 "pathname": "me@example.net" 1532 } 1533 }, 1534 { 1535 "href": "unix:/run/foo.socket?timeout=10", 1536 "new_value": "/var/log/../run/bar.socket", 1537 "expected": { 1538 "href": "unix:/var/run/bar.socket?timeout=10", 1539 "pathname": "/var/run/bar.socket" 1540 } 1541 }, 1542 { 1543 "href": "https://example.net#nav", 1544 "new_value": "home", 1545 "expected": { 1546 "href": "https://example.net/home#nav", 1547 "pathname": "/home" 1548 } 1549 }, 1550 { 1551 "href": "https://example.net#nav", 1552 "new_value": "../home", 1553 "expected": { 1554 "href": "https://example.net/home#nav", 1555 "pathname": "/home" 1556 } 1557 }, 1558 { 1559 "comment": "\\ is a segment delimiter for 'special' URLs", 1560 "href": "http://example.net/home?lang=fr#nav", 1561 "new_value": "\\a\\%2E\\b\\%2e.\\c", 1562 "expected": { 1563 "href": "http://example.net/a/c?lang=fr#nav", 1564 "pathname": "/a/c" 1565 } 1566 }, 1567 { 1568 "comment": "\\ is *not* a segment delimiter for non-'special' URLs", 1569 "href": "view-source+http://example.net/home?lang=fr#nav", 1570 "new_value": "\\a\\%2E\\b\\%2e.\\c", 1571 "expected": { 1572 "href": "view-source+http://example.net/\\a\\%2E\\b\\%2e.\\c?lang=fr#nav", 1573 "pathname": "/\\a\\%2E\\b\\%2e.\\c" 1574 } 1575 }, 1576 { 1577 "comment": "UTF-8 percent encoding with the default encode set. Tabs and newlines are removed.", 1578 "href": "a:/", 1579 "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé", 1580 "expected": { 1581 "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", 1582 "pathname": "/%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E%3F@AZ[\\]^_%60az%7B|%7D~%7F%C2%80%C2%81%C3%89%C3%A9" 1583 } 1584 }, 1585 { 1586 "comment": "Bytes already percent-encoded are left as-is, including %2E outside dotted segments.", 1587 "href": "http://example.net", 1588 "new_value": "%2e%2E%c3%89té", 1589 "expected": { 1590 "href": "http://example.net/%2e%2E%c3%89t%C3%A9", 1591 "pathname": "/%2e%2E%c3%89t%C3%A9" 1592 } 1593 }, 1594 { 1595 "comment": "? needs to be encoded", 1596 "href": "http://example.net", 1597 "new_value": "?", 1598 "expected": { 1599 "href": "http://example.net/%3F", 1600 "pathname": "/%3F" 1601 } 1602 }, 1603 { 1604 "comment": "# needs to be encoded", 1605 "href": "http://example.net", 1606 "new_value": "#", 1607 "expected": { 1608 "href": "http://example.net/%23", 1609 "pathname": "/%23" 1610 } 1611 }, 1612 { 1613 "comment": "? needs to be encoded, non-special scheme", 1614 "href": "sc://example.net", 1615 "new_value": "?", 1616 "expected": { 1617 "href": "sc://example.net/%3F", 1618 "pathname": "/%3F" 1619 } 1620 }, 1621 { 1622 "comment": "# needs to be encoded, non-special scheme", 1623 "href": "sc://example.net", 1624 "new_value": "#", 1625 "expected": { 1626 "href": "sc://example.net/%23", 1627 "pathname": "/%23" 1628 } 1629 }, 1630 { 1631 "comment": "File URLs and (back)slashes", 1632 "href": "file://monkey/", 1633 "new_value": "\\\\", 1634 "expected": { 1635 "href": "file://monkey/", 1636 "pathname": "/" 1637 } 1638 }, 1639 { 1640 "comment": "File URLs and (back)slashes", 1641 "href": "file:///unicorn", 1642 "new_value": "//\\/", 1643 "expected": { 1644 "href": "file:///", 1645 "pathname": "/" 1646 } 1647 }, 1648 { 1649 "comment": "File URLs and (back)slashes", 1650 "href": "file:///unicorn", 1651 "new_value": "//monkey/..//", 1652 "expected": { 1653 "href": "file:///", 1654 "pathname": "/" 1655 } 1656 } 1657 ], 1658 "search": [ 1659 { 1660 "href": "https://example.net#nav", 1661 "new_value": "lang=fr", 1662 "expected": { 1663 "href": "https://example.net/?lang=fr#nav", 1664 "search": "?lang=fr" 1665 } 1666 }, 1667 { 1668 "href": "https://example.net?lang=en-US#nav", 1669 "new_value": "lang=fr", 1670 "expected": { 1671 "href": "https://example.net/?lang=fr#nav", 1672 "search": "?lang=fr" 1673 } 1674 }, 1675 { 1676 "href": "https://example.net?lang=en-US#nav", 1677 "new_value": "?lang=fr", 1678 "expected": { 1679 "href": "https://example.net/?lang=fr#nav", 1680 "search": "?lang=fr" 1681 } 1682 }, 1683 { 1684 "href": "https://example.net?lang=en-US#nav", 1685 "new_value": "??lang=fr", 1686 "expected": { 1687 "href": "https://example.net/??lang=fr#nav", 1688 "search": "??lang=fr" 1689 } 1690 }, 1691 { 1692 "href": "https://example.net?lang=en-US#nav", 1693 "new_value": "?", 1694 "expected": { 1695 "href": "https://example.net/?#nav", 1696 "search": "" 1697 } 1698 }, 1699 { 1700 "href": "https://example.net?lang=en-US#nav", 1701 "new_value": "", 1702 "expected": { 1703 "href": "https://example.net/#nav", 1704 "search": "" 1705 } 1706 }, 1707 { 1708 "href": "https://example.net?lang=en-US", 1709 "new_value": "", 1710 "expected": { 1711 "href": "https://example.net/", 1712 "search": "" 1713 } 1714 }, 1715 { 1716 "href": "https://example.net", 1717 "new_value": "", 1718 "expected": { 1719 "href": "https://example.net/", 1720 "search": "" 1721 } 1722 }, 1723 { 1724 "comment": "UTF-8 percent encoding with the query encode set. Tabs and newlines are removed.", 1725 "href": "a:/", 1726 "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé", 1727 "expected": { 1728 "href": "a:/?%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_`az{|}~%7F%C2%80%C2%81%C3%89%C3%A9", 1729 "search": "?%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_`az{|}~%7F%C2%80%C2%81%C3%89%C3%A9" 1730 } 1731 }, 1732 { 1733 "comment": "Bytes already percent-encoded are left as-is", 1734 "href": "http://example.net", 1735 "new_value": "%c3%89té", 1736 "expected": { 1737 "href": "http://example.net/?%c3%89t%C3%A9", 1738 "search": "?%c3%89t%C3%A9" 1739 } 1740 } 1741 ], 1742 "hash": [ 1743 { 1744 "href": "https://example.net", 1745 "new_value": "main", 1746 "expected": { 1747 "href": "https://example.net/#main", 1748 "hash": "#main" 1749 } 1750 }, 1751 { 1752 "href": "https://example.net#nav", 1753 "new_value": "main", 1754 "expected": { 1755 "href": "https://example.net/#main", 1756 "hash": "#main" 1757 } 1758 }, 1759 { 1760 "href": "https://example.net?lang=en-US", 1761 "new_value": "##nav", 1762 "expected": { 1763 "href": "https://example.net/?lang=en-US##nav", 1764 "hash": "##nav" 1765 } 1766 }, 1767 { 1768 "href": "https://example.net?lang=en-US#nav", 1769 "new_value": "#main", 1770 "expected": { 1771 "href": "https://example.net/?lang=en-US#main", 1772 "hash": "#main" 1773 } 1774 }, 1775 { 1776 "href": "https://example.net?lang=en-US#nav", 1777 "new_value": "#", 1778 "expected": { 1779 "href": "https://example.net/?lang=en-US#", 1780 "hash": "" 1781 } 1782 }, 1783 { 1784 "href": "https://example.net?lang=en-US#nav", 1785 "new_value": "", 1786 "expected": { 1787 "href": "https://example.net/?lang=en-US", 1788 "hash": "" 1789 } 1790 }, 1791 { 1792 "href": "http://example.net", 1793 "new_value": "#foo bar", 1794 "expected": { 1795 "href": "http://example.net/#foo%20bar", 1796 "hash": "#foo%20bar" 1797 } 1798 }, 1799 { 1800 "href": "http://example.net", 1801 "new_value": "#foo\"bar", 1802 "expected": { 1803 "href": "http://example.net/#foo%22bar", 1804 "hash": "#foo%22bar" 1805 } 1806 }, 1807 { 1808 "href": "http://example.net", 1809 "new_value": "#foo<bar", 1810 "expected": { 1811 "href": "http://example.net/#foo%3Cbar", 1812 "hash": "#foo%3Cbar" 1813 } 1814 }, 1815 { 1816 "href": "http://example.net", 1817 "new_value": "#foo>bar", 1818 "expected": { 1819 "href": "http://example.net/#foo%3Ebar", 1820 "hash": "#foo%3Ebar" 1821 } 1822 }, 1823 { 1824 "href": "http://example.net", 1825 "new_value": "#foo`bar", 1826 "expected": { 1827 "href": "http://example.net/#foo%60bar", 1828 "hash": "#foo%60bar" 1829 } 1830 }, 1831 { 1832 "comment": "Simple percent-encoding; tabs and newlines are removed", 1833 "href": "a:/", 1834 "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé", 1835 "expected": { 1836 "href": "a:/#%00%01%1F%20!%22#$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9", 1837 "hash": "#%00%01%1F%20!%22#$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9" 1838 } 1839 }, 1840 { 1841 "comment": "Percent-encode NULLs in fragment", 1842 "href": "http://example.net", 1843 "new_value": "a\u0000b", 1844 "expected": { 1845 "href": "http://example.net/#a%00b", 1846 "hash": "#a%00b" 1847 } 1848 }, 1849 { 1850 "comment": "Percent-encode NULLs in fragment", 1851 "href": "non-spec:/", 1852 "new_value": "a\u0000b", 1853 "expected": { 1854 "href": "non-spec:/#a%00b", 1855 "hash": "#a%00b" 1856 } 1857 }, 1858 { 1859 "comment": "Bytes already percent-encoded are left as-is", 1860 "href": "http://example.net", 1861 "new_value": "%c3%89té", 1862 "expected": { 1863 "href": "http://example.net/#%c3%89t%C3%A9", 1864 "hash": "#%c3%89t%C3%A9" 1865 } 1866 }, 1867 { 1868 "href": "javascript:alert(1)", 1869 "new_value": "castle", 1870 "expected": { 1871 "href": "javascript:alert(1)#castle", 1872 "hash": "#castle" 1873 } 1874 } 1875 ] 1876} 1877