1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 // Run by: cd objdir; make -C netwerk/test/ xpcshell-tests
9 // or: cd objdir; make SOLO_FILE="test_URIs.js" -C netwerk/test/ check-one
11 // See also test_URIs2.js.
13 // Relevant RFCs: 1738, 1808, 2396, 3986 (newer than the code)
14 // http://greenbytes.de/tech/webdav/rfc3986.html#rfc.section.5.4
15 // http://greenbytes.de/tech/tc/uris/
24 pathQueryRef
: "blank",
34 pathQueryRef
: "foobar",
41 spec
: "chrome://foobar/somedir/somefile.xml",
43 prePath
: "chrome://foobar",
44 pathQueryRef
: "/somedir/somefile.xml",
51 spec
: "data:text/html;charset=utf-8,<html></html>",
54 pathQueryRef
: "text/html;charset=utf-8,<html></html>",
60 spec
: "data:text/html;charset=utf-8,<html>\r\n\t</html>",
63 pathQueryRef
: "text/html;charset=utf-8,<html></html>",
69 spec
: "data:text/plain,hello%20world",
72 pathQueryRef
: "text/plain,hello%20world",
78 spec
: "data:text/plain,hello world",
81 pathQueryRef
: "text/plain,hello world",
87 spec
: "file:///dir/afile",
90 pathQueryRef
: "text/plain,2",
92 relativeURI
: "data:te\nxt/plain,2",
115 spec
: "file:///myFile.html",
118 pathQueryRef
: "/myFile.html",
124 spec
: "file:///dir/afile",
127 pathQueryRef
: "/dir/data/text/plain,2",
129 relativeURI
: "data/text/plain,2",
134 spec
: "file:///dir/dir2/",
137 pathQueryRef
: "/dir/dir2/data/text/plain,2",
139 relativeURI
: "data/text/plain,2",
144 spec
: "ftp://ftp.mozilla.org/pub/mozilla.org/README",
146 prePath
: "ftp://ftp.mozilla.org",
147 pathQueryRef
: "/pub/mozilla.org/README",
153 spec
: "ftp://foo:bar@ftp.mozilla.org:100/pub/mozilla.org/README",
155 prePath
: "ftp://foo:bar@ftp.mozilla.org:100",
159 pathQueryRef
: "/pub/mozilla.org/README",
165 spec
: "ftp://foo:@ftp.mozilla.org:100/pub/mozilla.org/README",
167 prePath
: "ftp://foo@ftp.mozilla.org:100",
171 pathQueryRef
: "/pub/mozilla.org/README",
178 spec
: "gopher://mozilla.org/",
180 prePath
: "gopher://mozilla.org",
187 spec
: "http://www.example.com/",
189 prePath
: "http://www.example.com",
196 spec
: "http://www.exa\nmple.com/",
198 prePath
: "http://www.example.com",
205 spec
: "http://10.32.4.239/",
207 prePath
: "http://10.32.4.239",
215 spec
: "http://[::192.9.5.5]/ipng",
217 prePath
: "http://[::c009:505]",
219 pathQueryRef
: "/ipng",
225 spec
: "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:8888/index.html",
227 prePath
: "http://[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:8888",
228 host
: "fedc:ba98:7654:3210:fedc:ba98:7654:3210",
230 pathQueryRef
: "/index.html",
236 spec
: "http://bar:foo@www.mozilla.org:8080/pub/mozilla.org/README.html",
238 prePath
: "http://bar:foo@www.mozilla.org:8080",
242 host
: "www.mozilla.org",
243 pathQueryRef
: "/pub/mozilla.org/README.html",
249 spec
: "jar:resource://!/",
252 pathQueryRef
: "resource:///!/",
258 spec
: "jar:resource://gre/chrome.toolkit.jar!/",
261 pathQueryRef
: "resource://gre/chrome.toolkit.jar!/",
267 spec
: "mailto:webmaster@mozilla.com",
270 pathQueryRef
: "webmaster@mozilla.com",
276 spec
: "javascript:new Date()",
277 scheme
: "javascript",
278 prePath
: "javascript:",
279 pathQueryRef
: "new Date()",
288 pathQueryRef
: "123456",
295 spec
: "place:sort=8&maxResults=10",
298 pathQueryRef
: "sort=8&maxResults=10",
304 spec
: "resource://gre/",
306 prePath
: "resource://gre",
313 spec
: "resource://gre/components/",
315 prePath
: "resource://gre",
316 pathQueryRef
: "/components/",
322 // Adding more? Consider adding to test_URIs2.js instead, so that neither
323 // test runs for *too* long, risking timeouts on slow platforms.
326 var gHashSuffixes
= ["#", "#myRef", "#myRef?a=b", "#myRef#", "#myRef#x:yz"];
328 // TEST HELPER FUNCTIONS
329 // ---------------------
330 function do_info(text
, stack
) {
332 stack
= Components
.stack
.caller
;
349 // Checks that the URIs satisfy equals(), in both possible orderings.
350 // Also checks URI.equalsExceptRef(), because equal URIs should also be equal
351 // when we ignore the ref.
353 // The third argument is optional. If the client passes a third argument
354 // (e.g. todo_check_true), we'll use that in lieu of ok.
355 function do_check_uri_eq(aURI1
, aURI2
, aCheckTrueFunc
= ok
) {
356 do_info("(uri equals check: '" + aURI1
.spec
+ "' == '" + aURI2
.spec
+ "')");
357 aCheckTrueFunc(aURI1
.equals(aURI2
));
358 do_info("(uri equals check: '" + aURI2
.spec
+ "' == '" + aURI1
.spec
+ "')");
359 aCheckTrueFunc(aURI2
.equals(aURI1
));
361 // (Only take the extra step of testing 'equalsExceptRef' when we expect the
362 // URIs to really be equal. In 'todo' cases, the URIs may or may not be
363 // equal when refs are ignored - there's no way of knowing in general.)
364 if (aCheckTrueFunc
== ok
) {
365 do_check_uri_eqExceptRef(aURI1
, aURI2
, aCheckTrueFunc
);
369 // Checks that the URIs satisfy equalsExceptRef(), in both possible orderings.
371 // The third argument is optional. If the client passes a third argument
372 // (e.g. todo_check_true), we'll use that in lieu of ok.
373 function do_check_uri_eqExceptRef(aURI1
, aURI2
, aCheckTrueFunc
= ok
) {
375 "(uri equalsExceptRef check: '" + aURI1
.spec
+ "' == '" + aURI2
.spec
+ "')"
377 aCheckTrueFunc(aURI1
.equalsExceptRef(aURI2
));
379 "(uri equalsExceptRef check: '" + aURI2
.spec
+ "' == '" + aURI1
.spec
+ "')"
381 aCheckTrueFunc(aURI2
.equalsExceptRef(aURI1
));
384 // Checks that the given property on aURI matches the corresponding property
385 // in the test bundle (or matches some function of that corresponding property,
386 // if aTestFunctor is passed in).
387 function do_check_property(aTest
, aURI
, aPropertyName
, aTestFunctor
) {
388 if (aTest
[aPropertyName
]) {
389 var expectedVal
= aTestFunctor
390 ? aTestFunctor(aTest
[aPropertyName
])
391 : aTest
[aPropertyName
];
397 (aTestFunctor
? "modified '" : "'") +
403 Assert
.equal(aURI
[aPropertyName
], expectedVal
);
407 // Test that a given URI parses correctly into its various components.
408 function do_test_uri_basic(aTest
) {
415 (aTest
.relativeURI
=== undefined ? "(none)" : aTest
.relativeURI
)
419 URI
= NetUtil
.newURI(aTest
.spec
);
421 do_info("Caught error on parse of" + aTest
.spec
+ " Error: " + e
.result
);
423 Assert
.equal(e
.result
, aTest
.result
);
429 if (aTest
.relativeURI
) {
433 relURI
= Services
.io
.newURI(aTest
.relativeURI
, null, URI
);
436 "Caught error on Relative parse of " +
443 if (aTest
.relativeFail
) {
444 Assert
.equal(e
.result
, aTest
.relativeFail
);
450 "relURI.pathQueryRef = " +
451 relURI
.pathQueryRef
+
456 do_info("URI.pathQueryRef now = " + URI
.pathQueryRef
);
460 do_info("testing " + aTest
.spec
+ " equals a clone of itself");
461 do_check_uri_eq(URI
, URI
.mutate().finalize());
462 do_check_uri_eqExceptRef(URI
, URI
.mutate().setRef("").finalize());
463 do_info("testing " + aTest
.spec
+ " instanceof nsIURL");
464 Assert
.equal(URI
instanceof Ci
.nsIURL
, aTest
.nsIURL
);
465 do_info("testing " + aTest
.spec
+ " instanceof nsINestedURI");
466 Assert
.equal(URI
instanceof Ci
.nsINestedURI
, aTest
.nsINestedURI
);
471 " throws or returns false " +
474 // XXXdholbert At some point it'd probably be worth making this behavior
475 // (throwing vs. returning false) consistent across URI implementations.
479 isEqualToNull
= URI
.equals(null);
483 Assert
.ok(threw
|| !isEqualToNull
);
485 // Check the various components
486 do_check_property(aTest
, URI
, "scheme");
487 do_check_property(aTest
, URI
, "prePath");
488 do_check_property(aTest
, URI
, "pathQueryRef");
489 do_check_property(aTest
, URI
, "query");
490 do_check_property(aTest
, URI
, "ref");
491 do_check_property(aTest
, URI
, "port");
492 do_check_property(aTest
, URI
, "username");
493 do_check_property(aTest
, URI
, "password");
494 do_check_property(aTest
, URI
, "host");
495 do_check_property(aTest
, URI
, "specIgnoringRef");
497 do_info("testing hasRef");
498 Assert
.equal(URI
.hasRef
, !!aTest
.ref
, "URI.hasRef is correct");
499 do_info("testing hasUserPass");
502 !!aTest
.username
|| !!aTest
.password
,
503 "URI.hasUserPass is correct"
507 // Test that a given URI parses correctly when we add a given ref to the end
508 function do_test_uri_with_hash_suffix(aTest
, aSuffix
) {
509 do_info("making sure caller is using suffix that starts with '#'");
510 Assert
.equal(aSuffix
[0], "#");
512 var origURI
= NetUtil
.newURI(aTest
.spec
);
515 if (aTest
.relativeURI
) {
517 origURI
= Services
.io
.newURI(aTest
.relativeURI
, null, origURI
);
520 "Caught error on Relative parse of " +
530 testURI
= Services
.io
.newURI(aSuffix
, null, origURI
);
533 "Caught error adding suffix to " +
545 testURI
= NetUtil
.newURI(aTest
.spec
+ aSuffix
);
554 "equals a clone of itself"
556 do_check_uri_eq(testURI
, testURI
.mutate().finalize());
561 " doesn't equal self with '" +
566 Assert
.ok(!origURI
.equals(testURI
));
571 " is equalExceptRef to self with '" +
575 do_check_uri_eqExceptRef(origURI
, testURI
);
577 Assert
.equal(testURI
.hasRef
, true);
580 // These tests fail if origURI has a ref
582 "testing setRef('') on " +
584 " is equal to no-ref version but not equal to ref version"
586 var cloneNoRef
= testURI
.mutate().setRef("").finalize(); // we used to clone here.
587 do_info("cloneNoRef: " + cloneNoRef
.spec
+ " hasRef: " + cloneNoRef
.hasRef
);
588 do_info("testURI: " + testURI
.spec
+ " hasRef: " + testURI
.hasRef
);
589 do_check_uri_eq(cloneNoRef
, origURI
);
590 Assert
.ok(!cloneNoRef
.equals(testURI
));
593 "testing cloneWithNewRef on " +
595 " with an empty ref is equal to no-ref version but not equal to ref version"
597 var cloneNewRef
= testURI
.mutate().setRef("").finalize();
598 do_check_uri_eq(cloneNewRef
, origURI
);
599 do_check_uri_eq(cloneNewRef
, cloneNoRef
);
600 Assert
.ok(!cloneNewRef
.equals(testURI
));
603 "testing cloneWithNewRef on " +
605 " with the same new ref is equal to ref version and not equal to no-ref version"
607 cloneNewRef
= origURI
.mutate().setRef(aSuffix
).finalize();
608 do_check_uri_eq(cloneNewRef
, testURI
);
609 Assert
.ok(cloneNewRef
.equals(testURI
));
612 do_check_property(aTest
, testURI
, "scheme");
613 do_check_property(aTest
, testURI
, "prePath");
615 // These don't work if it's a ref already because '+' doesn't give the right result
616 do_check_property(aTest
, testURI
, "pathQueryRef", function (aStr
) {
617 return aStr
+ aSuffix
;
619 do_check_property(aTest
, testURI
, "ref", function () {
620 return aSuffix
.substr(1);
625 // Tests various ways of setting & clearing a ref on a URI.
626 function do_test_mutate_ref(aTest
, aSuffix
) {
627 do_info("making sure caller is using suffix that starts with '#'");
628 Assert
.equal(aSuffix
[0], "#");
630 var refURIWithSuffix
= NetUtil
.newURI(aTest
.spec
+ aSuffix
);
631 var refURIWithoutSuffix
= NetUtil
.newURI(aTest
.spec
);
633 var testURI
= NetUtil
.newURI(aTest
.spec
);
635 // First: Try setting .ref to our suffix
637 "testing that setting .ref on " +
641 "' does what we expect"
643 testURI
= testURI
.mutate().setRef(aSuffix
).finalize();
644 do_check_uri_eq(testURI
, refURIWithSuffix
);
645 do_check_uri_eqExceptRef(testURI
, refURIWithoutSuffix
);
647 // Now try setting .ref but leave off the initial hash (expect same result)
648 var suffixLackingHash
= aSuffix
.substr(1);
649 if (suffixLackingHash
) {
650 // (skip this our suffix was *just* a #)
652 "testing that setting .ref on " +
656 "' does what we expect"
658 testURI
= testURI
.mutate().setRef(suffixLackingHash
).finalize();
659 do_check_uri_eq(testURI
, refURIWithSuffix
);
660 do_check_uri_eqExceptRef(testURI
, refURIWithoutSuffix
);
663 // Now, clear .ref (should get us back the original spec)
665 "testing that clearing .ref on " + testURI
.spec
+ " does what we expect"
667 testURI
= testURI
.mutate().setRef("").finalize();
668 do_check_uri_eq(testURI
, refURIWithoutSuffix
);
669 do_check_uri_eqExceptRef(testURI
, refURIWithSuffix
);
671 if (!aTest
.relativeURI
) {
672 // TODO: These tests don't work as-is for relative URIs.
674 // Now try setting .spec directly (including suffix) and then clearing .ref
675 var specWithSuffix
= aTest
.spec
+ aSuffix
;
677 "testing that setting spec to " +
679 " and then clearing ref does what we expect"
682 testURI
= testURI
.mutate().setSpec(specWithSuffix
).setRef("").finalize();
683 do_check_uri_eq(testURI
, refURIWithoutSuffix
);
684 do_check_uri_eqExceptRef(testURI
, refURIWithSuffix
);
686 // XXX nsIJARURI throws an exception in SetPath(), so skip it for next part.
687 if (!(testURI
instanceof Ci
.nsIJARURI
)) {
688 // Now try setting .pathQueryRef directly (including suffix) and then clearing .ref
689 // (same as above, but with now with .pathQueryRef instead of .spec)
690 testURI
= NetUtil
.newURI(aTest
.spec
);
692 var pathWithSuffix
= aTest
.pathQueryRef
+ aSuffix
;
694 "testing that setting path to " +
696 " and then clearing ref does what we expect"
700 .setPathQueryRef(pathWithSuffix
)
703 do_check_uri_eq(testURI
, refURIWithoutSuffix
);
704 do_check_uri_eqExceptRef(testURI
, refURIWithSuffix
);
706 // Also: make sure that clearing .pathQueryRef also clears .ref
707 testURI
= testURI
.mutate().setPathQueryRef(pathWithSuffix
).finalize();
709 "testing that clearing path from " +
713 testURI
= testURI
.mutate().setPathQueryRef("").finalize();
714 Assert
.equal(testURI
.ref
, "");
719 // Check that changing nested/about URIs works correctly.
720 add_task(function check_nested_mutations() {
722 let uri1
= Services
.io
.newURI("about:blank#");
723 let uri2
= Services
.io
.newURI("about:blank");
724 let uri3
= uri1
.mutate().setRef("").finalize();
725 do_check_uri_eq(uri3
, uri2
);
726 uri3
= uri2
.mutate().setRef("#").finalize();
727 do_check_uri_eq(uri3
, uri1
);
729 uri1
= Services
.io
.newURI("about:blank?something");
730 uri2
= Services
.io
.newURI("about:blank");
731 uri3
= uri1
.mutate().setQuery("").finalize();
732 do_check_uri_eq(uri3
, uri2
);
733 uri3
= uri2
.mutate().setQuery("something").finalize();
734 do_check_uri_eq(uri3
, uri1
);
736 uri1
= Services
.io
.newURI("about:blank?query#ref");
737 uri2
= Services
.io
.newURI("about:blank");
738 uri3
= uri1
.mutate().setPathQueryRef("blank").finalize();
739 do_check_uri_eq(uri3
, uri2
);
740 uri3
= uri2
.mutate().setPathQueryRef("blank?query#ref").finalize();
741 do_check_uri_eq(uri3
, uri1
);
744 uri1
= Services
.io
.newURI("view-source:http://example.com/path#");
745 uri2
= Services
.io
.newURI("view-source:http://example.com/path");
746 uri3
= uri1
.mutate().setRef("").finalize();
747 do_check_uri_eq(uri3
, uri2
);
748 uri3
= uri2
.mutate().setRef("#").finalize();
749 do_check_uri_eq(uri3
, uri1
);
751 uri1
= Services
.io
.newURI("view-source:http://example.com/path?something");
752 uri2
= Services
.io
.newURI("view-source:http://example.com/path");
753 uri3
= uri1
.mutate().setQuery("").finalize();
754 do_check_uri_eq(uri3
, uri2
);
755 uri3
= uri2
.mutate().setQuery("something").finalize();
756 do_check_uri_eq(uri3
, uri1
);
758 uri1
= Services
.io
.newURI("view-source:http://example.com/path?query#ref");
759 uri2
= Services
.io
.newURI("view-source:http://example.com/path");
760 uri3
= uri1
.mutate().setPathQueryRef("path").finalize();
761 do_check_uri_eq(uri3
, uri2
);
762 uri3
= uri2
.mutate().setPathQueryRef("path?query#ref").finalize();
763 do_check_uri_eq(uri3
, uri1
);
765 uri1
= Services
.io
.newURI("view-source:about:blank#");
766 uri2
= Services
.io
.newURI("view-source:about:blank");
767 uri3
= uri1
.mutate().setRef("").finalize();
768 do_check_uri_eq(uri3
, uri2
);
769 uri3
= uri2
.mutate().setRef("#").finalize();
770 do_check_uri_eq(uri3
, uri1
);
772 uri1
= Services
.io
.newURI("view-source:about:blank?something");
773 uri2
= Services
.io
.newURI("view-source:about:blank");
774 uri3
= uri1
.mutate().setQuery("").finalize();
775 do_check_uri_eq(uri3
, uri2
);
776 uri3
= uri2
.mutate().setQuery("something").finalize();
777 do_check_uri_eq(uri3
, uri1
);
779 uri1
= Services
.io
.newURI("view-source:about:blank?query#ref");
780 uri2
= Services
.io
.newURI("view-source:about:blank");
781 uri3
= uri1
.mutate().setPathQueryRef("blank").finalize();
782 do_check_uri_eq(uri3
, uri2
);
783 uri3
= uri2
.mutate().setPathQueryRef("blank?query#ref").finalize();
784 do_check_uri_eq(uri3
, uri1
);
787 add_task(function check_space_escaping() {
788 let uri
= Services
.io
.newURI("data:text/plain,hello%20world#space hash");
789 Assert
.equal(uri
.spec
, "data:text/plain,hello%20world#space%20hash");
790 uri
= Services
.io
.newURI("data:text/plain,hello%20world#space%20hash");
791 Assert
.equal(uri
.spec
, "data:text/plain,hello%20world#space%20hash");
792 uri
= Services
.io
.newURI("data:text/plain,hello world#space%20hash");
793 Assert
.equal(uri
.spec
, "data:text/plain,hello world#space%20hash");
794 uri
= Services
.io
.newURI("data:text/plain,hello world#space hash");
795 Assert
.equal(uri
.spec
, "data:text/plain,hello world#space%20hash");
796 uri
= Services
.io
.newURI("http://example.com/test path#test path");
797 uri
= Services
.io
.newURI("http://example.com/test%20path#test%20path");
800 add_task(function check_space_with_query_and_ref() {
801 let url
= Services
.io
.newURI("data:space");
802 Assert
.equal(url
.spec
, "data:space");
804 url
= Services
.io
.newURI("data:space ?");
805 Assert
.equal(url
.spec
, "data:space ?");
806 url
= Services
.io
.newURI("data:space #");
807 Assert
.equal(url
.spec
, "data:space #");
809 url
= Services
.io
.newURI("data:space?");
810 Assert
.equal(url
.spec
, "data:space?");
811 url
= Services
.io
.newURI("data:space#");
812 Assert
.equal(url
.spec
, "data:space#");
814 url
= Services
.io
.newURI("data:space ?query");
815 Assert
.equal(url
.spec
, "data:space ?query");
816 url
= url
.mutate().setQuery("").finalize();
817 Assert
.equal(url
.spec
, "data:space");
819 url
= Services
.io
.newURI("data:space #ref");
820 Assert
.equal(url
.spec
, "data:space #ref");
821 url
= url
.mutate().setRef("").finalize();
822 Assert
.equal(url
.spec
, "data:space");
824 url
= Services
.io
.newURI("data:space?query#ref");
825 Assert
.equal(url
.spec
, "data:space?query#ref");
826 url
= url
.mutate().setRef("").finalize();
827 Assert
.equal(url
.spec
, "data:space?query");
828 url
= url
.mutate().setQuery("").finalize();
829 Assert
.equal(url
.spec
, "data:space");
831 url
= Services
.io
.newURI("data:space#ref?query");
832 Assert
.equal(url
.spec
, "data:space#ref?query");
833 url
= url
.mutate().setQuery("").finalize();
834 Assert
.equal(url
.spec
, "data:space#ref?query");
835 url
= url
.mutate().setRef("").finalize();
836 Assert
.equal(url
.spec
, "data:space");
838 url
= Services
.io
.newURI("data:space ?query#ref");
839 Assert
.equal(url
.spec
, "data:space ?query#ref");
840 url
= url
.mutate().setRef("").finalize();
841 Assert
.equal(url
.spec
, "data:space ?query");
842 url
= url
.mutate().setQuery("").finalize();
843 Assert
.equal(url
.spec
, "data:space");
845 url
= Services
.io
.newURI("data:space #ref?query");
846 Assert
.equal(url
.spec
, "data:space #ref?query");
847 url
= url
.mutate().setQuery("").finalize();
848 Assert
.equal(url
.spec
, "data:space #ref?query");
849 url
= url
.mutate().setRef("").finalize();
850 Assert
.equal(url
.spec
, "data:space");
853 add_task(function check_schemeIsNull() {
854 let uri
= Services
.io
.newURI("data:text/plain,aaa");
855 Assert
.ok(!uri
.schemeIs(null));
856 uri
= Services
.io
.newURI("http://example.com");
857 Assert
.ok(!uri
.schemeIs(null));
858 uri
= Services
.io
.newURI("dummyscheme://example.com");
859 Assert
.ok(!uri
.schemeIs(null));
860 uri
= Services
.io
.newURI("jar:resource://gre/chrome.toolkit.jar!/");
861 Assert
.ok(!uri
.schemeIs(null));
862 uri
= Services
.io
.newURI("moz-icon://.unknown?size=32");
863 Assert
.ok(!uri
.schemeIs(null));
866 // Check that characters in the query of moz-extension aren't improperly unescaped (Bug 1547882)
867 add_task(function check_mozextension_query() {
868 let uri
= Services
.io
.newURI(
869 "moz-extension://a7d1572e-3beb-4d93-a920-c408fa09e8ea/_source/holding.html"
873 .setQuery("u=https%3A%2F%2Fnews.ycombinator.com%2F")
875 Assert
.equal(uri
.query
, "u=https%3A%2F%2Fnews.ycombinator.com%2F");
876 uri
= Services
.io
.newURI(
877 "moz-extension://a7d1572e-3beb-4d93-a920-c408fa09e8ea/_source/holding.html?u=https%3A%2F%2Fnews.ycombinator.com%2F"
881 "moz-extension://a7d1572e-3beb-4d93-a920-c408fa09e8ea/_source/holding.html?u=https%3A%2F%2Fnews.ycombinator.com%2F"
883 Assert
.equal(uri
.query
, "u=https%3A%2F%2Fnews.ycombinator.com%2F");
886 add_task(function check_resolve() {
887 let base
= Services
.io
.newURI("http://example.com");
888 let uri
= Services
.io
.newURI("tel::+371 27028456", "utf-8", base
);
889 Assert
.equal(uri
.spec
, "tel::+371 27028456");
892 add_task(function test_extra_protocols() {
894 let url
= Services
.io
.newURI("dweb://example.com/test");
895 Assert
.equal(url
.host
, "example.com");
898 url
= Services
.io
.newURI(
899 "dat://41f8a987cfeba80a037e51cc8357d513b62514de36f2f9b3d3eeec7a8fb3b5a5/"
903 "41f8a987cfeba80a037e51cc8357d513b62514de36f2f9b3d3eeec7a8fb3b5a5"
905 url
= Services
.io
.newURI("dat://example.com/test");
906 Assert
.equal(url
.host
, "example.com");
909 url
= Services
.io
.newURI(
910 "ipfs://bafybeiccfclkdtucu6y4yc5cpr6y3yuinr67svmii46v5cfcrkp47ihehy/frontend/license.txt"
912 Assert
.equal(url
.scheme
, "ipfs");
915 "bafybeiccfclkdtucu6y4yc5cpr6y3yuinr67svmii46v5cfcrkp47ihehy"
917 Assert
.equal(url
.filePath
, "/frontend/license.txt");
920 url
= Services
.io
.newURI("ipns://peerdium.gozala.io/index.html");
921 Assert
.equal(url
.scheme
, "ipns");
922 Assert
.equal(url
.host
, "peerdium.gozala.io");
923 Assert
.equal(url
.filePath
, "/index.html");
926 url
= Services
.io
.newURI("ssb://scuttlebutt.nz/index.html");
927 Assert
.equal(url
.scheme
, "ssb");
928 Assert
.equal(url
.host
, "scuttlebutt.nz");
929 Assert
.equal(url
.filePath
, "/index.html");
932 url
= Services
.io
.newURI(
933 "wtp://951ead31d09e4049fc1f21f137e233dd0589fcbd/blog/vim-tips/"
935 Assert
.equal(url
.scheme
, "wtp");
936 Assert
.equal(url
.host
, "951ead31d09e4049fc1f21f137e233dd0589fcbd");
937 Assert
.equal(url
.filePath
, "/blog/vim-tips/");
940 // TEST MAIN FUNCTION
941 // ------------------
942 add_task(function mainTest() {
943 // UTF-8 check - From bug 622981
945 let base
= Services
.io
.newURI("http://example.org/xenia?");
946 let resolved
= Services
.io
.newURI("?x", null, base
);
947 let expected
= Services
.io
.newURI("http://example.org/xenia?x");
949 "Bug 662981: ACSII - comparing " + resolved
.spec
+ " and " + expected
.spec
951 Assert
.ok(resolved
.equals(expected
));
953 // UTF-8 character "è"
954 // Bug 622981 was triggered by an empty query string
955 base
= Services
.io
.newURI("http://example.org/xènia?");
956 resolved
= Services
.io
.newURI("?x", null, base
);
957 expected
= Services
.io
.newURI("http://example.org/xènia?x");
959 "Bug 662981: UTF8 - comparing " + resolved
.spec
+ " and " + expected
.spec
961 Assert
.ok(resolved
.equals(expected
));
963 gTests
.forEach(function (aTest
) {
964 // Check basic URI functionality
965 do_test_uri_basic(aTest
);
968 // Try adding various #-prefixed strings to the ends of the URIs
969 gHashSuffixes
.forEach(function (aSuffix
) {
970 do_test_uri_with_hash_suffix(aTest
, aSuffix
);
971 if (!aTest
.immutable
) {
972 do_test_mutate_ref(aTest
, aSuffix
);
976 // For URIs that we couldn't mutate above due to them being immutable:
977 // Now we check that they're actually immutable.
978 if (aTest
.immutable
) {
979 Assert
.ok(aTest
.immutable
);
985 function check_round_trip_serialization(spec
) {
986 dump(`checking ${spec}\n`);
987 let uri
= Services
.io
.newURI(spec
);
988 let str
= serialize_to_escaped_string(uri
);
989 let other
= deserialize_from_escaped_string(str
).QueryInterface(Ci
.nsIURI
);
990 equal(other
.spec
, uri
.spec
);
993 add_task(function test_iconURI_serialization() {
994 // URIs taken from test_moz_icon_uri.js
997 "moz-icon://foo.html?contentType=bar&size=button&state=normal",
998 "moz-icon://foo.html?size=3",
999 "moz-icon://stock/foo",
1000 "moz-icon:file://foo.txt",
1001 "moz-icon://file://foo.txt",
1004 tests
.forEach(str
=> check_round_trip_serialization(str
));
1007 add_task(function test_jarURI_serialization() {
1008 check_round_trip_serialization("jar:http://example.com/bar.jar!/");
1011 add_task(async
function round_trip_invalid_ace_label() {
1012 // This is well-formed punycode, but an invalid ACE label due to hyphens in
1013 // positions 3 & 4 and trailing hyphen. (Punycode-decode yields "xn--d淾-")
1014 let uri
= Services
.io
.newURI("http://xn--xn--d--fg4n/");
1015 Assert
.equal(uri
.spec
, "http://xn--xn--d--fg4n/");
1017 // Entirely invalid punycode will throw a MALFORMED error.
1018 Assert
.throws(() => {
1019 uri
= Services
.io
.newURI("http://a.b.c.XN--pokxncvks");
1020 }, /NS_ERROR_MALFORMED_URI/);
1023 add_task(async
function test_bug1875119() {
1024 let uri1
= Services
.io
.newURI("file:///path");
1025 let uri2
= Services
.io
.newURI("resource://test/bla");
1026 // type of uri2 is still SubstitutingURL which overrides the implementation of EnsureFile,
1027 // but it's scheme is now file.
1028 // See https://bugzilla.mozilla.org/show_bug.cgi?id=1876483 to disallow this
1029 uri2
= uri2
.mutate().setSpec("file:///path2").finalize();
1030 // NOTE: this test was originally expecting `uri1.equals(uri2)` to be throwing
1031 // a NS_NOINTERFACE error (instead of hitting a crash) when the new test landed
1032 // as part of Bug 1875119, then as a side-effect of the fix applied by Bug 1926106
1033 // the expected behavior is for the call to not raise an NS_NOINTERFACE error anymore
1034 // but to be returning false instead (and so the test has been adjusted accordingly).
1035 Assert
.ok(!uri1
.equals(uri2
), "Expect uri1.equals(uri2) to be false");
1038 add_task(async
function test_bug1843717() {
1039 // Make sure file path normalization on windows
1040 // doesn't affect the hash of the URL.
1041 let base
= Services
.io
.newURI("file:///abc\\def/");
1042 let uri
= Services
.io
.newURI("foo\\bar#x\\y", null, base
);
1043 Assert
.equal(uri
.spec
, "file:///abc/def/foo/bar#x\\y");
1044 uri
= Services
.io
.newURI("foo\\bar#xy", null, base
);
1045 Assert
.equal(uri
.spec
, "file:///abc/def/foo/bar#xy");
1046 uri
= Services
.io
.newURI("foo\\bar#", null, base
);
1047 Assert
.equal(uri
.spec
, "file:///abc/def/foo/bar#");
1050 add_task(async
function test_bug1874118() {
1051 let base
= Services
.io
.newURI("file:///tmp/mock/path");
1052 let uri
= Services
.io
.newURI("file:c:\\\\foo\\\\bar.html", null, base
);
1053 Assert
.equal(uri
.spec
, "file:///c://foo//bar.html");
1055 base
= Services
.io
.newURI("file:///tmp/mock/path");
1056 uri
= Services
.io
.newURI("file:c|\\\\foo\\\\bar.html", null, base
);
1057 Assert
.equal(uri
.spec
, "file:///c://foo//bar.html");
1059 base
= Services
.io
.newURI("file:///C:/");
1060 uri
= Services
.io
.newURI("..", null, base
);
1061 Assert
.equal(uri
.spec
, "file:///C:/");
1063 base
= Services
.io
.newURI("file:///");
1064 uri
= Services
.io
.newURI("C|/hello/../../", null, base
);
1065 Assert
.equal(uri
.spec
, "file:///C:/");
1067 base
= Services
.io
.newURI("file:///");
1068 uri
= Services
.io
.newURI("/C:/../../", null, base
);
1069 Assert
.equal(uri
.spec
, "file:///C:/");
1071 base
= Services
.io
.newURI("file:///");
1072 uri
= Services
.io
.newURI("/C://../../", null, base
);
1073 Assert
.equal(uri
.spec
, "file:///C:/");
1075 base
= Services
.io
.newURI("file:///tmp/mock/path");
1076 uri
= Services
.io
.newURI("C|/foo/bar", null, base
);
1077 Assert
.equal(uri
.spec
, "file:///C:/foo/bar");
1079 base
= Services
.io
.newURI("file:///tmp/mock/path");
1080 uri
= Services
.io
.newURI("/C|/foo/bar", null, base
);
1081 Assert
.equal(uri
.spec
, "file:///C:/foo/bar");
1084 add_task(async
function test_bug1911529() {
1087 "https://github.com/coder/coder/edit/main/docs/./enterprise.md",
1088 "https://github.com/coder/coder/edit/main/docs/enterprise.md",
1091 ["https://domain.com/.", "https://domain.com/", ""],
1092 ["https://domain.com/%2e", "https://domain.com/", ""],
1093 ["https://domain.com/%2e%2E", "https://domain.com/", ""],
1094 ["https://domain.com/%2e%2E/.", "https://domain.com/", ""],
1095 ["https://domain.com/./test.md", "https://domain.com/test.md", "test"],
1097 "https://domain.com/dir/sub/%2e%2e/%2e/test.md",
1098 "https://domain.com/dir/test.md",
1101 ["https://domain.com/dir/..", "https://domain.com/", ""],
1104 for (let t
of testcases
) {
1105 let uri
= Services
.io
.newURI(t
[0]);
1106 let uri2
= Services
.io
.newURI(t
[1]);
1107 Assert
.ok(uri
.equals(uri2
), `${uri} must equal ${uri2}`);
1108 Assert
.equal(t
[2], uri
.QueryInterface(Ci
.nsIURL
).fileBaseName
);
1112 add_task(async
function test_bug1939493() {
1113 let uri
= Services
.io
.newURI("resource:///components/");
1121 Assert
.equal(uri
.spec
, "resource:///components/");
1123 Assert
.throws(() => {
1124 uri
= uri
.mutate().setUserPass("a:b").finalize();
1125 }, /NS_ERROR_UNEXPECTED/);
1126 Assert
.throws(() => {
1127 uri
= uri
.mutate().setUsername("a").finalize();
1128 }, /NS_ERROR_UNEXPECTED/);
1129 Assert
.throws(() => {
1130 uri
= uri
.mutate().setPassword("b").finalize();
1131 }, /NS_ERROR_UNEXPECTED/);
1132 Assert
.throws(() => {
1133 uri
= uri
.mutate().setPort(10).finalize();
1134 }, /NS_ERROR_UNEXPECTED/);
1136 // username, password and port doesn't really make sense for a resource URL
1137 // but they still behave as regular URLs so this should be valid.
1138 uri
= uri
.mutate().setHost("gre").finalize();
1139 Assert
.equal(uri
.spec
, "resource://gre/components/");
1140 uri
= uri
.mutate().setUserPass("a:b").finalize();
1141 Assert
.equal(uri
.spec
, "resource://a:b@gre/components/");
1142 uri
= uri
.mutate().setUsername("user").finalize();
1143 Assert
.equal(uri
.spec
, "resource://user:b@gre/components/");
1144 uri
= uri
.mutate().setPassword("pass").finalize();
1145 Assert
.equal(uri
.spec
, "resource://user:pass@gre/components/");
1146 uri
= uri
.mutate().setPort(10).finalize();
1147 Assert
.equal(uri
.spec
, "resource://user:pass@gre:10/components/");
1149 // Clearing the host should fail, as there are still user, port, pass in play.
1150 Assert
.throws(() => {
1151 uri
= uri
.mutate().setHost("").finalize();
1152 }, /NS_ERROR_MALFORMED_URI/);
1163 Assert
.equal(uri
.spec
, "resource:///components/");