]> git.proxmox.com Git - cargo.git/blob - vendor/url/tests/setters_tests.json
New upstream version 0.52.0
[cargo.git] / vendor / url / tests / setters_tests.json
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 }