3 const gPrefs = Services.prefs;
5 function symmetricEquality(expect, a, b) {
6 /* Use if/else instead of |do_check_eq(expect, a.spec == b.spec)| so
7 that we get the specs output on the console if the check fails.
10 /* Check all the sub-pieces too, since that can help with
11 debugging cases when equals() returns something unexpected */
12 /* We don't check port in the loop, because it can be defaulted in
31 ].map(function (prop) {
32 dump("Testing '" + prop + "'\n");
33 Assert.equal(a[prop], b[prop]);
36 Assert.notEqual(a.spec, b.spec);
38 Assert.equal(expect, a.equals(b));
39 Assert.equal(expect, b.equals(a));
42 function stringToURL(str) {
43 return Cc["@mozilla.org/network/standard-url-mutator;1"]
44 .createInstance(Ci.nsIStandardURLMutator)
45 .init(Ci.nsIStandardURL.URLTYPE_AUTHORITY, 80, str, "UTF-8", null)
47 .QueryInterface(Ci.nsIURL);
50 function pairToURLs(pair) {
51 Assert.equal(pair.length, 2);
52 return pair.map(stringToURL);
55 add_test(function test_setEmptyPath() {
57 ["http://example.com", "http://example.com/tests/dom/tests"],
58 ["http://example.com:80", "http://example.com/tests/dom/tests"],
59 ["http://example.com:80/", "http://example.com/tests/dom/test"],
60 ["http://example.com/", "http://example.com/tests/dom/tests"],
61 ["http://example.com/a", "http://example.com/tests/dom/tests"],
62 ["http://example.com:80/a", "http://example.com/tests/dom/tests"],
65 for (var [provided, target] of pairs) {
66 symmetricEquality(false, target, provided);
68 provided = provided.mutate().setPathQueryRef("").finalize();
69 target = target.mutate().setPathQueryRef("").finalize();
71 Assert.equal(provided.spec, target.spec);
72 symmetricEquality(true, target, provided);
77 add_test(function test_setQuery() {
79 ["http://example.com", "http://example.com/?foo"],
80 ["http://example.com/bar", "http://example.com/bar?foo"],
81 ["http://example.com#bar", "http://example.com/?foo#bar"],
82 ["http://example.com/#bar", "http://example.com/?foo#bar"],
83 ["http://example.com/?longerthanfoo#bar", "http://example.com/?foo#bar"],
84 ["http://example.com/?longerthanfoo", "http://example.com/?foo"],
85 /* And one that's nonempty but shorter than "foo" */
86 ["http://example.com/?f#bar", "http://example.com/?foo#bar"],
87 ["http://example.com/?f", "http://example.com/?foo"],
90 for (var [provided, target] of pairs) {
91 symmetricEquality(false, provided, target);
97 .QueryInterface(Ci.nsIURL);
99 Assert.equal(provided.spec, target.spec);
100 symmetricEquality(true, provided, target);
103 [provided, target] = [
104 "http://example.com/#",
105 "http://example.com/?foo#bar",
107 symmetricEquality(false, provided, target);
112 .QueryInterface(Ci.nsIURL);
113 symmetricEquality(false, provided, target);
115 var newProvided = Services.io
116 .newURI("#bar", null, provided)
117 .QueryInterface(Ci.nsIURL);
119 Assert.equal(newProvided.spec, target.spec);
120 symmetricEquality(true, newProvided, target);
124 add_test(function test_setRef() {
126 ["http://example.com", "", "http://example.com/"],
127 ["http://example.com:80", "", "http://example.com:80/"],
128 ["http://example.com:80/", "", "http://example.com:80/"],
129 ["http://example.com/", "", "http://example.com/"],
130 ["http://example.com/a", "", "http://example.com/a"],
131 ["http://example.com:80/a", "", "http://example.com:80/a"],
133 ["http://example.com", "x", "http://example.com/#x"],
134 ["http://example.com:80", "x", "http://example.com:80/#x"],
135 ["http://example.com:80/", "x", "http://example.com:80/#x"],
136 ["http://example.com/", "x", "http://example.com/#x"],
137 ["http://example.com/a", "x", "http://example.com/a#x"],
138 ["http://example.com:80/a", "x", "http://example.com:80/a#x"],
140 ["http://example.com", "xx", "http://example.com/#xx"],
141 ["http://example.com:80", "xx", "http://example.com:80/#xx"],
142 ["http://example.com:80/", "xx", "http://example.com:80/#xx"],
143 ["http://example.com/", "xx", "http://example.com/#xx"],
144 ["http://example.com/a", "xx", "http://example.com/a#xx"],
145 ["http://example.com:80/a", "xx", "http://example.com:80/a#xx"],
148 "http://example.com",
150 "http://example.com/#xxxxxxxxxxxxxx",
153 "http://example.com:80",
155 "http://example.com:80/#xxxxxxxxxxxxxx",
158 "http://example.com:80/",
160 "http://example.com:80/#xxxxxxxxxxxxxx",
163 "http://example.com/",
165 "http://example.com/#xxxxxxxxxxxxxx",
168 "http://example.com/a",
170 "http://example.com/a#xxxxxxxxxxxxxx",
173 "http://example.com:80/a",
175 "http://example.com:80/a#xxxxxxxxxxxxxx",
179 for (var [before, ref, result] of tests) {
180 /* Test1: starting with empty ref */
181 var a = stringToURL(before);
182 a = a.mutate().setRef(ref).finalize().QueryInterface(Ci.nsIURL);
183 var b = stringToURL(result);
185 Assert.equal(a.spec, b.spec);
186 Assert.equal(ref, b.ref);
187 symmetricEquality(true, a, b);
189 /* Test2: starting with non-empty */
190 a = a.mutate().setRef("yyyy").finalize().QueryInterface(Ci.nsIURL);
191 var c = stringToURL(before);
192 c = c.mutate().setRef("yyyy").finalize().QueryInterface(Ci.nsIURL);
193 symmetricEquality(true, a, c);
195 /* Test3: reset the ref */
196 a = a.mutate().setRef("").finalize().QueryInterface(Ci.nsIURL);
197 symmetricEquality(true, a, stringToURL(before));
199 /* Test4: verify again after reset */
200 a = a.mutate().setRef(ref).finalize().QueryInterface(Ci.nsIURL);
201 symmetricEquality(true, a, b);
206 // Bug 960014 - Make nsStandardURL::SetHost less magical around IPv6
207 add_test(function test_ipv6() {
208 var url = stringToURL("http://example.com");
209 url = url.mutate().setHost("[2001::1]").finalize();
210 Assert.equal(url.host, "2001::1");
212 url = stringToURL("http://example.com");
213 url = url.mutate().setHostPort("[2001::1]:30").finalize();
214 Assert.equal(url.host, "2001::1");
215 Assert.equal(url.port, 30);
216 Assert.equal(url.hostPort, "[2001::1]:30");
218 url = stringToURL("http://example.com");
219 url = url.mutate().setHostPort("2001:1").finalize();
220 Assert.equal(url.host, "0.0.7.209");
221 Assert.equal(url.port, 1);
222 Assert.equal(url.hostPort, "0.0.7.209:1");
226 add_test(function test_ipv6_fail() {
227 var url = stringToURL("http://example.com");
231 url = url.mutate().setHost("2001::1").finalize();
233 /NS_ERROR_MALFORMED_URI/,
238 url = url.mutate().setHost("[2001::1]:20").finalize();
240 /NS_ERROR_MALFORMED_URI/,
245 url = url.mutate().setHost("[2001::1").finalize();
247 /NS_ERROR_MALFORMED_URI/,
248 "missing last bracket"
252 url = url.mutate().setHost("2001::1]").finalize();
254 /NS_ERROR_MALFORMED_URI/,
255 "missing first bracket"
259 url = url.mutate().setHost("2001[::1]").finalize();
261 /NS_ERROR_MALFORMED_URI/,
262 "bad bracket position"
266 url = url.mutate().setHost("[]").finalize();
268 /NS_ERROR_MALFORMED_URI/,
273 url = url.mutate().setHost("[hello]").finalize();
275 /NS_ERROR_MALFORMED_URI/,
280 url = url.mutate().setHost("[192.168.1.1]").finalize();
282 /NS_ERROR_MALFORMED_URI/,
287 url = url.mutate().setHostPort("2001::1").finalize();
289 /NS_ERROR_MALFORMED_URI/,
294 url = url.mutate().setHostPort("[2001::1]30").finalize();
296 /NS_ERROR_MALFORMED_URI/,
301 url = url.mutate().setHostPort("[2001:1]").finalize();
303 /NS_ERROR_MALFORMED_URI/,
308 url = url.mutate().setHostPort("[2001:1]10").finalize();
310 /NS_ERROR_MALFORMED_URI/,
315 url = url.mutate().setHostPort("[2001:1]10:20").finalize();
317 /NS_ERROR_MALFORMED_URI/,
322 url = url.mutate().setHostPort("[2001:1]:10:20").finalize();
324 /NS_ERROR_MALFORMED_URI/,
329 url = url.mutate().setHostPort("[2001:1").finalize();
331 /NS_ERROR_MALFORMED_URI/,
336 url = url.mutate().setHostPort("2001]:1").finalize();
338 /NS_ERROR_MALFORMED_URI/,
343 url = url.mutate().setHostPort("2001:1]").finalize();
345 /NS_ERROR_MALFORMED_URI/,
350 url = url.mutate().setHostPort("").finalize();
352 /NS_ERROR_UNEXPECTED/,
353 "Empty hostPort should fail"
356 // These checks used to fail, but now don't (see bug 1433958 comment 57)
357 url = url.mutate().setHostPort("[2001::1]:").finalize();
358 Assert.equal(url.spec, "http://[2001::1]/");
359 url = url.mutate().setHostPort("[2002::1]:bad").finalize();
360 Assert.equal(url.spec, "http://[2002::1]/");
365 add_test(function test_clearedSpec() {
366 var url = stringToURL("http://example.com/path");
369 url = url.mutate().setSpec("http: example").finalize();
371 /NS_ERROR_MALFORMED_URI/,
376 url = url.mutate().setSpec("").finalize();
378 /NS_ERROR_MALFORMED_URI/,
381 Assert.equal(url.spec, "http://example.com/path");
384 .setHost("allizom.org")
386 .QueryInterface(Ci.nsIURL);
388 var ref = stringToURL("http://allizom.org/path");
389 symmetricEquality(true, url, ref);
393 add_test(function test_escapeBrackets() {
395 var url = stringToURL("http://example.com/?a[x]=1");
396 Assert.equal(url.spec, "http://example.com/?a[x]=1");
398 url = stringToURL("http://example.com/?a%5Bx%5D=1");
399 Assert.equal(url.spec, "http://example.com/?a%5Bx%5D=1");
401 url = stringToURL("http://[2001::1]/?a[x]=1");
402 Assert.equal(url.spec, "http://[2001::1]/?a[x]=1");
404 url = stringToURL("http://[2001::1]/?a%5Bx%5D=1");
405 Assert.equal(url.spec, "http://[2001::1]/?a%5Bx%5D=1");
408 url = stringToURL("http://example.com/brackets[x]/test");
409 Assert.equal(url.spec, "http://example.com/brackets[x]/test");
411 url = stringToURL("http://example.com/a%5Bx%5D/test");
412 Assert.equal(url.spec, "http://example.com/a%5Bx%5D/test");
416 add_test(function test_escapeQuote() {
417 var url = stringToURL("http://example.com/#'");
418 Assert.equal(url.spec, "http://example.com/#'");
419 Assert.equal(url.ref, "'");
420 url = url.mutate().setRef("test'test").finalize();
421 Assert.equal(url.spec, "http://example.com/#test'test");
422 Assert.equal(url.ref, "test'test");
426 add_test(function test_apostropheEncoding() {
427 // For now, single quote is escaped everywhere _except_ the path.
428 // This policy is controlled by the bitmask in nsEscape.cpp::EscapeChars[]
429 var url = stringToURL("http://example.com/dir'/file'.ext'");
430 Assert.equal(url.spec, "http://example.com/dir'/file'.ext'");
434 add_test(function test_accentEncoding() {
435 var url = stringToURL("http://example.com/?hello=`");
436 Assert.equal(url.spec, "http://example.com/?hello=`");
437 Assert.equal(url.query, "hello=`");
439 url = stringToURL("http://example.com/?hello=%2C");
440 Assert.equal(url.spec, "http://example.com/?hello=%2C");
441 Assert.equal(url.query, "hello=%2C");
446 { skip_if: () => AppConstants.MOZ_APP_NAME == "thunderbird" },
447 function test_percentDecoding() {
448 var url = stringToURL("http://%70%61%73%74%65%62%69%6E.com");
449 Assert.equal(url.spec, "http://pastebin.com/");
451 // Disallowed hostname characters are rejected even when percent encoded
454 url = stringToURL("http://example.com%0a%23.google.com/");
456 /NS_ERROR_MALFORMED_URI/,
457 "invalid characters are not allowed"
463 add_test(function test_hugeStringThrows() {
464 let prefs = Services.prefs;
465 let maxLen = prefs.getIntPref("network.standard-url.max-length");
466 let url = stringToURL("http://test:test@example.com");
468 let hugeString = new Array(maxLen + 1).fill("a").join("");
470 { method: "setSpec", qi: Ci.nsIURIMutator },
471 { method: "setUsername", qi: Ci.nsIURIMutator },
472 { method: "setPassword", qi: Ci.nsIURIMutator },
473 { method: "setFilePath", qi: Ci.nsIURIMutator },
474 { method: "setHostPort", qi: Ci.nsIURIMutator },
475 { method: "setHost", qi: Ci.nsIURIMutator },
476 { method: "setUserPass", qi: Ci.nsIURIMutator },
477 { method: "setPathQueryRef", qi: Ci.nsIURIMutator },
478 { method: "setQuery", qi: Ci.nsIURIMutator },
479 { method: "setRef", qi: Ci.nsIURIMutator },
480 { method: "setScheme", qi: Ci.nsIURIMutator },
481 { method: "setFileName", qi: Ci.nsIURLMutator },
482 { method: "setFileExtension", qi: Ci.nsIURLMutator },
483 { method: "setFileBaseName", qi: Ci.nsIURLMutator },
486 for (let prop of setters) {
491 .QueryInterface(prop.qi)
492 [prop.method](hugeString)
494 /NS_ERROR_MALFORMED_URI/,
495 `Passing a huge string to "${prop.method}" should throw`
502 add_test(function test_verticalBar() {
503 var url = Services.io.newURI("file:///w|m");
504 Assert.equal(url.spec, "file:///w|m");
506 url = Services.io.newURI("file:///w||m");
507 Assert.equal(url.spec, "file:///w||m");
509 url = Services.io.newURI("file:///w|/m");
510 Assert.equal(url.spec, "file:///w:/m");
512 url = Services.io.newURI("file:C|/m/");
513 Assert.equal(url.spec, "file:///C:/m/");
515 url = Services.io.newURI("file:C||/m/");
516 Assert.equal(url.spec, "file:///C||/m/");
521 add_test(function test_pathPercentEncodedDot() {
522 var url = stringToURL("http://example.com/hello/%2e%2E/%2e");
523 Assert.equal(url.spec, "http://example.com/");
524 Assert.equal(url.directory, "/");
525 Assert.equal(url.fileName, "");
526 Assert.equal(url.fileBaseName, "");
527 Assert.equal(url.fileExtension, "");
529 url = stringToURL("http://example.com/hello/%2e%2E/%");
530 Assert.equal(url.spec, "http://example.com/%");
531 Assert.equal(url.directory, "/");
532 Assert.equal(url.fileName, "%");
533 Assert.equal(url.fileBaseName, "%");
534 Assert.equal(url.fileExtension, "");
536 url = stringToURL("http://example.com/hello/%2e%2E/%2");
537 Assert.equal(url.spec, "http://example.com/%2");
538 Assert.equal(url.directory, "/");
539 Assert.equal(url.fileName, "%2");
540 Assert.equal(url.fileBaseName, "%2");
541 Assert.equal(url.fileExtension, "");
543 url = stringToURL("http://example.com/hello/%2e%2E/%#");
544 Assert.equal(url.spec, "http://example.com/%#");
545 Assert.equal(url.directory, "/");
546 Assert.equal(url.fileName, "%");
547 Assert.equal(url.fileBaseName, "%");
548 Assert.equal(url.fileExtension, "");
550 url = stringToURL("http://example.com/hello/%2e%2E/%2?");
551 Assert.equal(url.spec, "http://example.com/%2?");
552 Assert.equal(url.directory, "/");
553 Assert.equal(url.fileName, "%2");
554 Assert.equal(url.fileBaseName, "%2");
555 Assert.equal(url.fileExtension, "");
557 url = stringToURL("http://example.com/hello/%2e/");
558 Assert.equal(url.spec, "http://example.com/hello/");
559 Assert.equal(url.directory, "/hello/");
560 Assert.equal(url.fileName, "");
561 Assert.equal(url.fileBaseName, "");
562 Assert.equal(url.fileExtension, "");
564 url = stringToURL("http://example.com/%2e");
565 Assert.equal(url.spec, "http://example.com/");
566 Assert.equal(url.directory, "/");
567 Assert.equal(url.fileName, "");
568 Assert.equal(url.fileBaseName, "");
569 Assert.equal(url.fileExtension, "");
571 url = stringToURL("http://example.com/.%2e");
572 Assert.equal(url.spec, "http://example.com/");
573 Assert.equal(url.directory, "/");
574 Assert.equal(url.fileName, "");
575 Assert.equal(url.fileBaseName, "");
576 Assert.equal(url.fileExtension, "");
578 url = stringToURL("http://example.com/%2e.");
579 Assert.equal(url.spec, "http://example.com/");
580 Assert.equal(url.directory, "/");
581 Assert.equal(url.fileName, "");
582 Assert.equal(url.fileBaseName, "");
583 Assert.equal(url.fileExtension, "");
585 url = stringToURL("http://example.com/%2e%2e");
586 Assert.equal(url.spec, "http://example.com/");
587 Assert.equal(url.directory, "/");
588 Assert.equal(url.fileName, "");
589 Assert.equal(url.fileBaseName, "");
590 Assert.equal(url.fileExtension, "");
592 url = stringToURL("http://example.com/%2e%2e%2e");
593 Assert.equal(url.spec, "http://example.com/%2e%2e%2e");
594 Assert.equal(url.directory, "/");
595 Assert.equal(url.fileName, "%2e%2e%2e");
596 Assert.equal(url.fileBaseName, "%2e%2e%2e");
597 Assert.equal(url.fileExtension, "");
599 url = stringToURL("http://example.com/%2e%2e%2e%2e");
600 Assert.equal(url.spec, "http://example.com/%2e%2e%2e%2e");
601 Assert.equal(url.directory, "/");
602 Assert.equal(url.fileName, "%2e%2e%2e%2e");
603 Assert.equal(url.fileBaseName, "%2e%2e%2e%2e");
604 Assert.equal(url.fileExtension, "");
606 url = stringToURL("http://example.com/hello/%2e%2");
607 Assert.equal(url.spec, "http://example.com/hello/%2e%2");
608 Assert.equal(url.directory, "/hello/");
609 Assert.equal(url.fileName, "%2e%2");
610 Assert.equal(url.fileBaseName, "%2e%2");
611 Assert.equal(url.fileExtension, "");
613 url = stringToURL("http://example.com/hello/%2e./%2e%2e/.%2e/%2e.bar");
614 Assert.equal(url.spec, "http://example.com/%2e.bar");
615 Assert.equal(url.directory, "/");
616 Assert.equal(url.fileName, "%2e.bar");
617 Assert.equal(url.fileBaseName, "%2e");
618 Assert.equal(url.fileExtension, "bar");
620 url = stringToURL("http://example.com/%2eX/X%2e/%2eX");
621 Assert.equal(url.spec, "http://example.com/%2eX/X%2e/%2eX");
622 Assert.equal(url.directory, "/%2eX/X%2e/");
623 Assert.equal(url.fileName, "%2eX");
624 Assert.equal(url.fileBaseName, "%2eX");
625 Assert.equal(url.fileExtension, "");
630 add_test(function test_filterWhitespace() {
631 let url = stringToURL(
632 " \r\n\th\nt\rt\tp://ex\r\n\tample.com/path\r\n\t/\r\n\tto the/fil\r\n\te.e\r\n\txt?que\r\n\try#ha\r\n\tsh \r\n\t "
636 "http://example.com/path/to%20the/file.ext?query#hash"
639 // These setters should filter \r\n\t.
640 url = stringToURL("http://test.com/path?query#hash");
641 url = url.mutate().setFilePath("pa\r\n\tth").finalize();
642 Assert.equal(url.spec, "http://test.com/path?query#hash");
643 url = url.mutate().setQuery("que\r\n\try").finalize();
644 Assert.equal(url.spec, "http://test.com/path?query#hash");
645 url = url.mutate().setRef("ha\r\n\tsh").finalize();
646 Assert.equal(url.spec, "http://test.com/path?query#hash");
649 .QueryInterface(Ci.nsIURLMutator)
650 .setFileName("fi\r\n\tle.name")
652 Assert.equal(url.spec, "http://test.com/fi%0D%0A%09le.name?query#hash");
657 add_test(function test_backslashReplacement() {
658 var url = stringToURL(
659 "http:\\\\test.com\\path/to\\file?query\\backslash#hash\\"
663 "http://test.com/path/to/file?query\\backslash#hash\\"
666 url = stringToURL("http:\\\\test.com\\example.org/path\\to/file");
667 Assert.equal(url.spec, "http://test.com/example.org/path/to/file");
668 Assert.equal(url.host, "test.com");
669 Assert.equal(url.pathQueryRef, "/example.org/path/to/file");
674 add_test(function test_authority_host() {
677 stringToURL("http:");
679 /NS_ERROR_MALFORMED_URI/,
680 "TYPE_AUTHORITY should have host"
684 stringToURL("http:///");
686 /NS_ERROR_MALFORMED_URI/,
687 "TYPE_AUTHORITY should have host"
693 add_test(function test_trim_C0_and_space() {
694 var url = stringToURL(
695 "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f http://example.com/ \x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f "
697 Assert.equal(url.spec, "http://example.com/");
701 "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f http://test.com/ \x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f "
704 Assert.equal(url.spec, "http://test.com/");
710 "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19 "
714 /NS_ERROR_MALFORMED_URI/,
720 // This tests that C0-and-space characters in the path, query and ref are
722 add_test(function test_encode_C0_and_space() {
724 var hex = d.toString(16);
725 if (hex.length == 1) {
728 return hex.toUpperCase();
731 for (var i = 0x0; i <= 0x20; i++) {
732 // These characters get filtered - they are not encoded.
734 String.fromCharCode(i) == "\r" ||
735 String.fromCharCode(i) == "\n" ||
736 String.fromCharCode(i) == "\t"
740 let url = stringToURL(
741 "http://example.com/pa" +
742 String.fromCharCode(i) +
744 String.fromCharCode(i) +
746 String.fromCharCode(i) +
751 "http://example.com/pa%" +
761 // Additionally, we need to check the setters.
762 let url = stringToURL("http://example.com/path?query#hash");
763 url = url.mutate().setFilePath("pa\0th").finalize();
764 Assert.equal(url.spec, "http://example.com/pa%00th?query#hash");
765 url = url.mutate().setQuery("qu\0ery").finalize();
766 Assert.equal(url.spec, "http://example.com/pa%00th?qu%00ery#hash");
767 url = url.mutate().setRef("ha\0sh").finalize();
768 Assert.equal(url.spec, "http://example.com/pa%00th?qu%00ery#ha%00sh");
771 .QueryInterface(Ci.nsIURLMutator)
772 .setFileName("fi\0le.name")
774 Assert.equal(url.spec, "http://example.com/fi%00le.name?qu%00ery#ha%00sh");
779 add_test(function test_ipv4Normalize() {
785 "http://0177.00.00.01",
788 "http://00000000000000000000000000177.0000000.0000000.0001",
789 "http://000000177.0000001",
790 "http://017700000001",
791 "http://0x7f.0x00.0x00.0x01",
794 "http://0x007f.0x0000.0x0000.0x0001",
795 "http://000177.0.00000.0x0001",
800 for (url of localIPv4s) {
801 Assert.equal(url.spec, "http://127.0.0.1/");
804 // These should treated as a domain instead of an IPv4.
810 "resource://4294967296/",
813 for (spec of nonIPv4s) {
814 url = stringToURL(spec);
815 Assert.equal(url.spec, spec);
818 url = stringToURL("resource://path/to/resource/");
819 url = url.mutate().setHost("123").finalize();
820 Assert.equal(url.host, "123");
825 add_test(function test_invalidHostChars() {
826 var url = stringToURL("http://example.org/");
827 for (let i = 0; i <= 0x20; i++) {
828 // These characters get filtered.
830 String.fromCharCode(i) == "\r" ||
831 String.fromCharCode(i) == "\n" ||
832 String.fromCharCode(i) == "\t"
840 .setHost("a" + String.fromCharCode(i) + "b")
843 /NS_ERROR_MALFORMED_URI/,
844 "Trying to set hostname containing char code: " + i
847 for (let c of '@[]*<>|:"') {
855 /NS_ERROR_MALFORMED_URI/,
856 "Trying to set hostname containing char: " + c
860 // It also can't contain /, \, #, ?, but we treat these characters as
861 // hostname separators, so there is no way to set them and fail.
865 add_test(function test_normalize_ipv6() {
866 var url = stringToURL("http://example.com");
867 url = url.mutate().setHost("[::192.9.5.5]").finalize();
868 Assert.equal(url.spec, "http://[::c009:505]/");
873 add_test(function test_emptyPassword() {
874 var url = stringToURL("http://a:@example.com");
875 Assert.equal(url.spec, "http://a@example.com/");
876 url = url.mutate().setPassword("pp").finalize();
877 Assert.equal(url.spec, "http://a:pp@example.com/");
878 url = url.mutate().setPassword("").finalize();
879 Assert.equal(url.spec, "http://a@example.com/");
880 url = url.mutate().setUserPass("xxx:").finalize();
881 Assert.equal(url.spec, "http://xxx@example.com/");
882 url = url.mutate().setPassword("zzzz").finalize();
883 Assert.equal(url.spec, "http://xxx:zzzz@example.com/");
884 url = url.mutate().setUserPass("xxxxx:yyyyyy").finalize();
885 Assert.equal(url.spec, "http://xxxxx:yyyyyy@example.com/");
886 url = url.mutate().setUserPass("z:").finalize();
887 Assert.equal(url.spec, "http://z@example.com/");
888 url = url.mutate().setPassword("ppppppppppp").finalize();
889 Assert.equal(url.spec, "http://z:ppppppppppp@example.com/");
891 url = stringToURL("http://example.com");
892 url = url.mutate().setPassword("").finalize(); // Still empty. Should work.
893 Assert.equal(url.spec, "http://example.com/");
898 add_test(function test_emptyUser() {
899 let url = stringToURL("http://:a@example.com/path/to/something?query#hash");
900 Assert.equal(url.spec, "http://:a@example.com/path/to/something?query#hash");
901 url = stringToURL("http://:@example.com/path/to/something?query#hash");
902 Assert.equal(url.spec, "http://example.com/path/to/something?query#hash");
904 const kurl = stringToURL(
905 "http://user:pass@example.com:8888/path/to/something?query#hash"
907 url = kurl.mutate().setUsername("").finalize();
910 "http://:pass@example.com:8888/path/to/something?query#hash"
912 Assert.equal(url.host, "example.com");
913 Assert.equal(url.hostPort, "example.com:8888");
914 Assert.equal(url.filePath, "/path/to/something");
915 Assert.equal(url.query, "query");
916 Assert.equal(url.ref, "hash");
917 url = kurl.mutate().setUserPass(":pass1").finalize();
920 "http://:pass1@example.com:8888/path/to/something?query#hash"
922 Assert.equal(url.host, "example.com");
923 Assert.equal(url.hostPort, "example.com:8888");
924 Assert.equal(url.filePath, "/path/to/something");
925 Assert.equal(url.query, "query");
926 Assert.equal(url.ref, "hash");
927 url = url.mutate().setUsername("user2").finalize();
930 "http://user2:pass1@example.com:8888/path/to/something?query#hash"
932 Assert.equal(url.host, "example.com");
933 url = url.mutate().setUserPass(":pass234").finalize();
936 "http://:pass234@example.com:8888/path/to/something?query#hash"
938 Assert.equal(url.host, "example.com");
939 url = url.mutate().setUserPass("").finalize();
942 "http://example.com:8888/path/to/something?query#hash"
944 Assert.equal(url.host, "example.com");
945 url = url.mutate().setPassword("pa").finalize();
948 "http://:pa@example.com:8888/path/to/something?query#hash"
950 Assert.equal(url.host, "example.com");
951 url = url.mutate().setUserPass("user:pass").finalize();
952 symmetricEquality(true, url.QueryInterface(Ci.nsIURL), kurl);
954 url = stringToURL("http://example.com:8888/path/to/something?query#hash");
955 url = url.mutate().setPassword("pass").finalize();
958 "http://:pass@example.com:8888/path/to/something?query#hash"
960 url = url.mutate().setUsername("").finalize();
963 "http://:pass@example.com:8888/path/to/something?query#hash"
966 url = stringToURL("http://example.com:8888");
967 url = url.mutate().setUsername("user").finalize();
968 url = url.mutate().setUsername("").finalize();
969 Assert.equal(url.spec, "http://example.com:8888/");
971 url = stringToURL("http://:pass@example.com");
972 Assert.equal(url.spec, "http://:pass@example.com/");
973 url = url.mutate().setPassword("").finalize();
974 Assert.equal(url.spec, "http://example.com/");
975 url = url.mutate().setUserPass("user:pass").finalize();
976 Assert.equal(url.spec, "http://user:pass@example.com/");
977 Assert.equal(url.host, "example.com");
978 url = url.mutate().setUserPass("u:p").finalize();
979 Assert.equal(url.spec, "http://u:p@example.com/");
980 Assert.equal(url.host, "example.com");
981 url = url.mutate().setUserPass("u1:p23").finalize();
982 Assert.equal(url.spec, "http://u1:p23@example.com/");
983 Assert.equal(url.host, "example.com");
984 url = url.mutate().setUsername("u").finalize();
985 Assert.equal(url.spec, "http://u:p23@example.com/");
986 Assert.equal(url.host, "example.com");
987 url = url.mutate().setPassword("p").finalize();
988 Assert.equal(url.spec, "http://u:p@example.com/");
989 Assert.equal(url.host, "example.com");
991 url = url.mutate().setUserPass("u2:p2").finalize();
992 Assert.equal(url.spec, "http://u2:p2@example.com/");
993 Assert.equal(url.host, "example.com");
994 url = url.mutate().setUserPass("u23:p23").finalize();
995 Assert.equal(url.spec, "http://u23:p23@example.com/");
996 Assert.equal(url.host, "example.com");
1001 registerCleanupFunction(function () {
1002 gPrefs.clearUserPref("network.standard-url.punycode-host");
1005 add_test(function test_idna_host() {
1006 // See bug 945240 - this test makes sure that URLs return a punycode hostname
1007 let url = stringToURL(
1008 "http://user:password@ält.example.org:8080/path?query#etc"
1010 equal(url.host, "xn--lt-uia.example.org");
1011 equal(url.hostPort, "xn--lt-uia.example.org:8080");
1012 equal(url.prePath, "http://user:password@xn--lt-uia.example.org:8080");
1015 "http://user:password@xn--lt-uia.example.org:8080/path?query#etc"
1018 url.specIgnoringRef,
1019 "http://user:password@xn--lt-uia.example.org:8080/path?query"
1023 .QueryInterface(Ci.nsISensitiveInfoHiddenURI)
1024 .getSensitiveInfoHiddenSpec(),
1025 "http://user:****@xn--lt-uia.example.org:8080/path?query#etc"
1028 equal(url.displayHost, "ält.example.org");
1029 equal(url.displayHostPort, "ält.example.org:8080");
1032 "http://user:password@ält.example.org:8080/path?query#etc"
1035 equal(url.asciiHost, "xn--lt-uia.example.org");
1036 equal(url.asciiHostPort, "xn--lt-uia.example.org:8080");
1039 "http://user:password@xn--lt-uia.example.org:8080/path?query#etc"
1042 url = url.mutate().setRef("").finalize(); // SetRef calls InvalidateCache()
1045 "http://user:password@xn--lt-uia.example.org:8080/path?query"
1049 "http://user:password@ält.example.org:8080/path?query"
1053 "http://user:password@xn--lt-uia.example.org:8080/path?query"
1056 url = stringToURL("http://user:password@www.ält.com:8080/path?query#etc");
1057 url = url.mutate().setRef("").finalize();
1058 equal(url.spec, "http://user:password@www.xn--lt-uia.com:8080/path?query");
1064 { skip_if: () => AppConstants.MOZ_APP_NAME == "thunderbird" },
1065 function test_bug1517025() {
1068 stringToURL("https://b%9a/");
1070 /NS_ERROR_MALFORMED_URI/,
1076 stringToURL("https://b%9ª/");
1078 /NS_ERROR_MALFORMED_URI/,
1082 let base = stringToURL(
1083 "https://bug1517025.bmoattachments.org/attachment.cgi?id=9033787"
1087 Services.io.newURI("/\\b%9ª", "windows-1252", base);
1089 /NS_ERROR_MALFORMED_URI/,
1097 add_task(async function test_emptyHostWithURLType() {
1098 let makeURL = (str, type) => {
1099 return Cc["@mozilla.org/network/standard-url-mutator;1"]
1100 .createInstance(Ci.nsIStandardURLMutator)
1101 .init(type, 80, str, "UTF-8", null)
1103 .QueryInterface(Ci.nsIURL);
1106 let url = makeURL("http://foo.com/bar/", Ci.nsIStandardURL.URLTYPE_AUTHORITY);
1108 () => url.mutate().setHost("").finalize().spec,
1109 /NS_ERROR_UNEXPECTED/,
1110 "Empty host is not allowed for URLTYPE_AUTHORITY"
1113 url = makeURL("http://foo.com/bar/", Ci.nsIStandardURL.URLTYPE_STANDARD);
1115 () => url.mutate().setHost("").finalize().spec,
1116 /NS_ERROR_UNEXPECTED/,
1117 "Empty host is not allowed for URLTYPE_STANDARD"
1120 url = makeURL("http://foo.com/bar/", Ci.nsIStandardURL.URLTYPE_NO_AUTHORITY);
1124 "Host is removed when parsing URLTYPE_NO_AUTHORITY"
1127 url.mutate().setHost("").finalize().spec,
1129 "Setting an empty host does nothing for URLTYPE_NO_AUTHORITY"
1132 () => url.mutate().setHost("something").finalize().spec,
1133 /NS_ERROR_UNEXPECTED/,
1134 "Setting a non-empty host is not allowed for URLTYPE_NO_AUTHORITY"
1137 url.mutate().setHost("#j").finalize().spec,
1139 "Setting a pseudo-empty host does nothing for URLTYPE_NO_AUTHORITY"
1143 "http://example.org:123/foo?bar#baz",
1144 Ci.nsIStandardURL.URLTYPE_AUTHORITY
1147 () => url.mutate().setHost("#j").finalize().spec,
1148 /NS_ERROR_UNEXPECTED/,
1149 "A pseudo-empty host is not allowed for URLTYPE_AUTHORITY"
1153 add_task(async function test_fuzz() {
1154 let makeURL = str => {
1156 Cc["@mozilla.org/network/standard-url-mutator;1"]
1157 .createInstance(Ci.nsIStandardURLMutator)
1158 .QueryInterface(Ci.nsIURIMutator)
1159 // .init(type, 80, str, "UTF-8", null)
1162 .QueryInterface(Ci.nsIURL)
1166 Assert.throws(() => {
1167 let url = makeURL("/");
1168 url.mutate().setHost("(").finalize();
1169 }, /NS_ERROR_MALFORMED_URI/);
1172 add_task(async function test_bug1648493() {
1173 let url = stringToURL("https://example.com/");
1174 url = url.mutate().setScheme("file").finalize();
1175 url = url.mutate().setScheme("resource").finalize();
1176 url = url.mutate().setPassword("ê").finalize();
1177 url = url.mutate().setUsername("ç").finalize();
1178 url = url.mutate().setScheme("t").finalize();
1179 equal(url.spec, "t://%C3%83%C2%A7:%C3%83%C2%AA@example.com/");
1180 equal(url.username, "%C3%83%C2%A7");
1183 add_task(async function test_bug1873976() {
1184 let url = Services.io.newURI("file:.");
1185 equal(url.spec, "file:///");
1188 add_task(async function test_bug1890346() {
1189 let url = Services.io.newURI("file:..?/..");
1190 equal(url.spec, "file:///?/..");
1193 add_task(async function test_bug1914141() {
1194 equal(Services.io.isValidHostname("example.com"), true);
1195 equal(Services.io.isValidHostname("example.0"), false);
1197 equal(Services.io.isValidHostname("192.168.0.1"), true);
1198 equal(Services.io.isValidHostname("192.168.0"), true);
1199 equal(Services.io.isValidHostname("1.192.168.0.1"), false);
1200 equal(Services.io.isValidHostname("invalid.192.168.0.1"), false);
1202 equal(Services.io.isValidHostname("::1"), true);
1203 equal(Services.io.isValidHostname("abcd::zz::00"), false);
1204 equal(Services.io.isValidHostname("zzzz::1.2.3.4"), false);
1206 equal(Services.io.isValidHostname("::1.2.3.4"), true);