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://user@foo.com/bar/", Ci
.nsIStandardURL
.URLTYPE_STANDARD
);
1115 () => url
.mutate().setHost("").finalize().spec
,
1116 /NS_ERROR_MALFORMED_URI/,
1117 "Setting an empty host should throw if there is a username present"
1121 "http://:password@foo.com/bar/",
1122 Ci
.nsIStandardURL
.URLTYPE_STANDARD
1125 () => url
.mutate().setHost("").finalize().spec
,
1126 /NS_ERROR_MALFORMED_URI/,
1127 "Setting an empty host should throw if there is a password present"
1130 url
= makeURL("http://foo.com:123/bar/", Ci
.nsIStandardURL
.URLTYPE_STANDARD
);
1132 () => url
.mutate().setHost("").finalize().spec
,
1133 /NS_ERROR_MALFORMED_URI/,
1134 "Setting an empty host should throw if there is a port present"
1137 url
= makeURL("http://foo.com/bar/", Ci
.nsIStandardURL
.URLTYPE_STANDARD
);
1138 Assert
.equal(url
.mutate().setHost("").finalize().spec
, "http:///bar/");
1140 url
= makeURL("http://foo.com/bar/", Ci
.nsIStandardURL
.URLTYPE_NO_AUTHORITY
);
1144 "Host is removed when parsing URLTYPE_NO_AUTHORITY"
1147 url
.mutate().setHost("").finalize().spec
,
1149 "Setting an empty host does nothing for URLTYPE_NO_AUTHORITY"
1152 () => url
.mutate().setHost("something").finalize().spec
,
1153 /NS_ERROR_UNEXPECTED/,
1154 "Setting a non-empty host is not allowed for URLTYPE_NO_AUTHORITY"
1157 url
.mutate().setHost("#j").finalize().spec
,
1159 "Setting a pseudo-empty host does nothing for URLTYPE_NO_AUTHORITY"
1163 "http://example.org:123/foo?bar#baz",
1164 Ci
.nsIStandardURL
.URLTYPE_AUTHORITY
1167 () => url
.mutate().setHost("#j").finalize().spec
,
1168 /NS_ERROR_UNEXPECTED/,
1169 "A pseudo-empty host is not allowed for URLTYPE_AUTHORITY"
1173 add_task(async
function test_fuzz() {
1174 let makeURL
= str
=> {
1176 Cc
["@mozilla.org/network/standard-url-mutator;1"]
1177 .createInstance(Ci
.nsIStandardURLMutator
)
1178 .QueryInterface(Ci
.nsIURIMutator
)
1179 // .init(type, 80, str, "UTF-8", null)
1182 .QueryInterface(Ci
.nsIURL
)
1186 Assert
.throws(() => {
1187 let url
= makeURL("/");
1188 url
.mutate().setHost("(").finalize();
1189 }, /NS_ERROR_MALFORMED_URI/);
1192 add_task(async
function test_bug1648493() {
1193 let url
= stringToURL("https://example.com/");
1194 url
= url
.mutate().setScheme("file").finalize();
1195 url
= url
.mutate().setScheme("resource").finalize();
1196 url
= url
.mutate().setPassword("ê").finalize();
1197 url
= url
.mutate().setUsername("ç").finalize();
1198 url
= url
.mutate().setScheme("t").finalize();
1199 equal(url
.spec
, "t://%C3%83%C2%A7:%C3%83%C2%AA@example.com/");
1200 equal(url
.username
, "%C3%83%C2%A7");
1203 add_task(async
function test_bug1873976() {
1204 let url
= Services
.io
.newURI("file:.");
1205 equal(url
.spec
, "file:///");
1208 add_task(async
function test_bug1890346() {
1209 let url
= Services
.io
.newURI("file:..?/..");
1210 equal(url
.spec
, "file:///?/..");
1213 add_task(async
function test_bug1914141() {
1214 equal(Services
.io
.isValidHostname("example.com"), true);
1215 equal(Services
.io
.isValidHostname("example.0"), false);
1217 equal(Services
.io
.isValidHostname("192.168.0.1"), true);
1218 equal(Services
.io
.isValidHostname("192.168.0"), true);
1219 equal(Services
.io
.isValidHostname("1.192.168.0.1"), false);
1220 equal(Services
.io
.isValidHostname("invalid.192.168.0.1"), false);
1222 equal(Services
.io
.isValidHostname("::1"), true);
1223 equal(Services
.io
.isValidHostname("abcd::zz::00"), false);
1224 equal(Services
.io
.isValidHostname("zzzz::1.2.3.4"), false);
1226 equal(Services
.io
.isValidHostname("::1.2.3.4"), true);