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