|
1 | 1 | <!DOCTYPE html>
|
2 | 2 | <meta charset='utf-8'>
|
3 |
| -<title>registerProtocolHandler()</title> |
| 3 | +<title>protocol handlers</title> |
4 | 4 |
|
5 | 5 | <script src='/resources/testharness.js'></script>
|
6 | 6 | <script src='/resources/testharnessreport.js'></script>
|
|
11 | 11 | registration requests on a page, you might need to disable or significantly
|
12 | 12 | increase that limit for the tests below to run.</p>
|
13 | 13 |
|
14 |
| -<div id='log'></div> |
15 |
| - |
16 | 14 | <script type='text/javascript'>
|
17 |
| - |
18 |
| -test(function () { |
| 15 | +test(() => { |
19 | 16 | assert_idl_attribute(navigator, 'registerProtocolHandler');
|
20 | 17 | }, 'the registerProtocolHandler method should exist on the navigator object');
|
21 | 18 |
|
22 |
| -test(function () { |
23 |
| - navigator.registerProtocolHandler('tel', location.href + '/%s', 'foo'); |
24 |
| -}, 'a handler with valid arguments should work'); |
25 |
| - |
| 19 | +test(() => { |
| 20 | + assert_idl_attribute(navigator, 'unregisterProtocolHandler'); |
| 21 | +}, 'the unregisterProtocolHandler method should exist on the navigator object'); |
26 | 22 |
|
27 | 23 | /* URL argument */
|
28 |
| -test(function () { |
29 |
| - navigator.registerProtocolHandler('tel', '%s', 'foo'); |
30 |
| -}, 'a relative URL should work'); |
31 |
| - |
32 |
| -test(function () { |
33 |
| - navigator.registerProtocolHandler('tel', location.href + '#%s', 'foo'); |
34 |
| -}, 'a URL with a fragment identifier should work'); |
35 |
| - |
36 |
| -test(function () { |
37 |
| - navigator.registerProtocolHandler('tel', location.href + '?foo=%s', 'foo'); |
38 |
| -}, 'a URL with a query string should work'); |
39 |
| - |
40 |
| -test(function () { |
41 |
| - navigator.registerProtocolHandler('tel', location.href + '?foo=%s&bar', 'foo'); |
42 |
| -}, 'a URL with a multi-argument query string should work'); |
43 |
| - |
44 |
| -test(function () { |
45 |
| - navigator.registerProtocolHandler('tel', location.href + '/%s/bar/baz/', 'foo'); |
46 |
| -}, 'a URL with the passed string as a directory name should work'); |
47 |
| - |
48 |
| -test(function () { |
49 |
| - navigator.registerProtocolHandler('tel', location.href + '/%s/bar/baz/?foo=1337&bar#baz', 'foo'); |
50 |
| -}, 'a URL with the passed string as a directory name followed by a query string and fragment identifier should work'); |
51 |
| - |
52 |
| -test(function () { |
53 |
| - navigator.registerProtocolHandler('tel', location.href + '/%s/foo/%s/', 'foo'); |
54 |
| -}, 'a URL with the passed string included twice should work'); |
55 |
| - |
56 |
| -test(function () { |
57 |
| - assert_throws('SYNTAX_ERR', function () { navigator.registerProtocolHandler('mailto', '', 'foo') } ); |
58 |
| -}, 'an empty url argument should throw SYNTAX_ERR'); |
59 |
| - |
60 |
| -test(function () { |
61 |
| - assert_throws('SECURITY_ERR', function () { navigator.registerProtocolHandler('mailto', 'http://%s.com', 'foo') } ); |
62 |
| -}, '%s instead of domain name should throw SECURITY_ERR'); |
63 |
| - |
64 |
| -test(function () { |
65 |
| - assert_throws('SECURITY_ERR', function () { navigator.registerProtocolHandler('mailto', 'http://%s.example.com', 'foo') } ); |
66 |
| -}, '%s instead of subdomain name should throw SECURITY_ERR'); |
67 |
| - |
68 |
| -test(function () { |
69 |
| - assert_throws('SYNTAX_ERR', function () { navigator.registerProtocolHandler('mailto', location.href + '', 'foo') } ); |
70 |
| -}, 'a url argument without %s should throw SYNTAX_ERR'); |
71 |
| - |
72 |
| -test(function () { |
73 |
| - assert_throws('SYNTAX_ERR', function () { navigator.registerProtocolHandler('mailto', 'http://example.com', 'foo') } ); |
74 |
| -}, 'a url argument pointing to a different domain name, without %s should throw SYNTAX_ERR'); |
75 |
| - |
76 |
| -test(function () { |
77 |
| - assert_throws('SYNTAX_ERR', function () { navigator.registerProtocolHandler('mailto', location.href + '/%', 'foo') } ); |
78 |
| -}, 'a url argument without %s (but with %) should throw SYNTAX_ERR'); |
79 |
| - |
80 |
| -test(function () { |
81 |
| - assert_throws('SYNTAX_ERR', function () { navigator.registerProtocolHandler('mailto', location.href + '/%a', 'foo') } ); |
82 |
| -}, 'a url argument without %s (but with %a) should throw SYNTAX_ERR'); |
83 |
| - |
84 |
| -test(function () { |
85 |
| - assert_throws('SECURITY_ERR', function () { navigator.registerProtocolHandler('mailto', 'http://example.com/%s', 'foo') } ); |
86 |
| -}, 'a url argument pointing to a different domain name should throw SECURITY_ERR'); |
87 |
| - |
88 |
| -test(function () { |
89 |
| - assert_throws('SECURITY_ERR', function () { navigator.registerProtocolHandler('mailto', 'https://example.com/%s', 'foo') } ); |
90 |
| -}, 'a url argument pointing to a different domain name should throw SECURITY_ERR (2)'); |
91 |
| - |
92 |
| -test(function () { |
93 |
| - assert_throws('SECURITY_ERR', function () { navigator.registerProtocolHandler('mailto', 'http://foobar.example.com/%s', 'foo') } ); |
94 |
| -}, 'a url argument pointing to a different domain name should throw SECURITY_ERR (3)'); |
| 24 | +const vaild_urls = [ |
| 25 | + '%s', |
| 26 | + location.href + '/%s', |
| 27 | + location.href + '#%s', |
| 28 | + location.href + '?foo=%s', |
| 29 | + location.href + '?foo=%s&bar', |
| 30 | + location.href + '/%s/bar/baz/', |
| 31 | + location.href + '/%s/bar/baz/?foo=1337&bar#baz', |
| 32 | + location.href + '/%s/foo/%s/', |
| 33 | +]; |
| 34 | +for (const url of vaild_urls) { |
| 35 | + test(() => { |
| 36 | + navigator.registerProtocolHandler('tel', url, 'foo'); |
| 37 | + }, 'registerProtocolHandler: Valid URL "' + url + '" should work.'); |
| 38 | + |
| 39 | + test(() => { |
| 40 | + navigator.unregisterProtocolHandler('tel', url); |
| 41 | + }, 'unregisterProtocolHandler: Valid URL "' + url + '" should work.'); |
| 42 | +} |
95 | 43 |
|
96 |
| -test(function () { |
97 |
| - assert_throws('SECURITY_ERR', function () { navigator.registerProtocolHandler('mailto', 'mailto:%[email protected]', 'foo') } ); |
98 |
| -}, 'looping handlers should throw SECURITY_ERR'); |
| 44 | +const invalid_urls1 = [ |
| 45 | + '', |
| 46 | + '%S', |
| 47 | + location.href + '', |
| 48 | + location.href + '/%', |
| 49 | + location.href + '/%a', |
| 50 | + 'http://example.com', |
| 51 | + 'http://[v8.:::]//url=%s', |
| 52 | +]; |
| 53 | + |
| 54 | +for (const url of invalid_urls1) { |
| 55 | + test(() => { |
| 56 | + assert_throws('SYNTAX_ERR', () => { navigator.registerProtocolHandler('mailto', url, 'foo'); }); |
| 57 | + }, 'registerProtocolHandler: Invalid URL "' + url + '" should throw SYNTAX_ERR.'); |
| 58 | + |
| 59 | + test(() => { |
| 60 | + assert_throws('SYNTAX_ERR', () => { navigator.unregisterProtocolHandler('mailto', url); }); |
| 61 | + }, 'unregisterProtocolHandler: Invalid URL "' + url + '" should throw SYNTAX_ERR.'); |
| 62 | +} |
99 | 63 |
|
100 |
| -test(function () { |
101 |
| - assert_throws('SECURITY_ERR', function () { navigator.registerProtocolHandler('sms', 'tel:%s', 'foo') } ); |
102 |
| -}, 'a url argument pointing to a non-http[s] scheme should throw SECURITY_ERR due to not being of the same origin'); |
| 64 | +const invaild_urls2 = [ |
| 65 | + 'http://%s.com', |
| 66 | + 'http://%s.example.com', |
| 67 | + 'http://example.com/%s', |
| 68 | + 'https://example.com/%s', |
| 69 | + 'http://foobar.example.com/%s', |
| 70 | + |
| 71 | + 'mailto:%s', |
| 72 | +]; |
| 73 | +for (const url of invaild_urls2) { |
| 74 | + test(() => { |
| 75 | + assert_throws('SECURITY_ERR', () => { navigator.registerProtocolHandler('mailto', url, 'foo'); }); |
| 76 | + }, 'registerProtocolHandler: Invalid URL "' + url + '" should throw SECURITY_ERR.'); |
| 77 | + |
| 78 | + test(() => { |
| 79 | + assert_throws('SECURITY_ERR', () => { navigator.unregisterProtocolHandler('mailto', url); }); |
| 80 | + }, 'unregisterProtocolHandler: Invalid URL "' + url + '" should throw SECURITY_ERR.'); |
| 81 | +} |
103 | 82 |
|
104 | 83 | /* Protocol argument */
|
105 |
| -test(function () { |
106 |
| - assert_throws('SYNTAX_ERR', function () { navigator.registerProtocolHandler('unrecognized', location.href + '/%a', 'foo') } ); |
107 |
| -}, 'a protocol argument containing an unrecognized scheme should throw SECURITY_ERR'); /* This is a whitelist, not a blacklist. */ |
108 |
| - |
109 |
| -test(function () { |
110 |
| - assert_throws('SYNTAX_ERR', function () { navigator.registerProtocolHandler('mailto:', location.href + '/%a', 'foo') } ); |
111 |
| -}, 'a protocol argument containing : should throw SYNTAX_ERR'); |
112 |
| - |
113 |
| -test(function () { |
114 |
| - assert_throws('SYNTAX_ERR', function () { navigator.registerProtocolHandler('mailto://', location.href + '/%a', 'foo') } ); |
115 |
| -}, 'a protocol argument containing :// should throw SYNTAX_ERR'); |
116 |
| - |
117 |
| -test(function () { |
118 |
| - assert_throws('SYNTAX_ERR', function () { navigator.registerProtocolHandler('http://', location.href + '/%a', 'foo') } ); |
119 |
| -}, 'a protocol argument containing http:// should throw SYNTAX_ERR'); |
120 |
| - |
121 |
| -test(function () { |
122 |
| - assert_throws('SYNTAX_ERR', function () { navigator.registerProtocolHandler('mailto' + String.fromCharCode(0), location.href + '/%a', 'foo') } ); |
123 |
| -}, 'a protocol argument containing a null character should throw SYNTAX_ERR'); |
124 |
| - |
125 |
| -test(function () { |
126 |
| - assert_throws('SYNTAX_ERR', function () { navigator.registerProtocolHandler('mailtoo' + String.fromCharCode(8), location.href + '/%a', 'foo') } ); |
127 |
| -}, 'a protocol argument containing a backspace character should throw SYNTAX_ERR'); |
128 |
| - |
129 |
| -test(function () { |
130 |
| - assert_throws('SYNTAX_ERR', function () { navigator.registerProtocolHandler('mailto' + String.fromCharCode(10), location.href + '/%a', 'foo') } ); |
131 |
| -}, 'a protocol argument containing a LF character should throw SYNTAX_ERR'); |
132 |
| - |
133 |
| -test(function () { |
134 |
| - assert_throws('SYNTAX_ERR', function () { navigator.registerProtocolHandler('mаilto', location.href + '/%a', 'foo') } ); |
135 |
| -}, 'a protocol argument containing non-alphanumeric characters (like a cyrillic “а”) should throw SYNTAX_ERR'); |
136 |
| - |
137 |
| -test(function () { |
138 |
| - navigator.registerProtocolHandler('TEL', location.href + '/%s', 'foo'); |
139 |
| -}, 'a protocol argument of “TEL” should be equivalent to “tel”'); |
140 |
| - |
141 |
| -test(function () { |
142 |
| - navigator.registerProtocolHandler('teL', location.href + '/%s', 'foo'); |
143 |
| -}, 'a protocol argument of “teL” should be equivalent to “tel”'); |
144 |
| - |
145 | 84 |
|
146 | 85 | /* Overriding any of the following protocols must never be allowed. That would
|
147 | 86 | * break the browser. */
|
148 |
| -var blacklist = new Array( |
| 87 | +const blacklist = [ |
149 | 88 | 'about',
|
150 | 89 | 'attachment',
|
151 | 90 | 'blob',
|
|
170 | 109 | 'view-source',
|
171 | 110 | 'ws',
|
172 | 111 | 'wss',
|
173 |
| - 'wyciwyg'); |
174 |
| - |
175 |
| -for ( var bi=0, bl=blacklist.length; bi<bl; ++bi ){ |
176 |
| - |
177 |
| - test(function () { |
178 |
| - assert_throws('SECURITY_ERR', function () { navigator.registerProtocolHandler(blacklist[bi], location.href + '/%s', 'foo') } ); |
179 |
| - }, 'attempting to override the ' + blacklist[bi] + ' protocol should throw SECURITY_ERR'); |
180 |
| - |
| 112 | + 'wyciwyg', |
| 113 | + /*other invalid schemes*/ |
| 114 | + 'unrecognized', |
| 115 | + 'mаilto', /*a cyrillic "а"*/ |
| 116 | + 'mailto:', |
| 117 | + 'mailto://', |
| 118 | + 'mailto' + String.fromCharCode(0), |
| 119 | + 'mailtoo' + String.fromCharCode(8), |
| 120 | + 'mailto' + String.fromCharCode(10), |
| 121 | + 'http://', |
| 122 | + 'ssh:/', |
| 123 | + 'magnet:+', |
| 124 | + 'tel:sip', |
| 125 | + 'web+', |
| 126 | +]; |
| 127 | +for (const scheme of blacklist) { |
| 128 | + test(() => { |
| 129 | + assert_throws('SECURITY_ERR', () => { navigator.registerProtocolHandler(scheme, location.href + '/%s', 'foo'); }); |
| 130 | + }, 'registerProtocolHandler: Attempting to override the "' + scheme + '" protocol should throw SECURITY_ERR.'); |
| 131 | + |
| 132 | + test(() => { |
| 133 | + assert_throws('SECURITY_ERR', () => { navigator.unregisterProtocolHandler(scheme, location.href + '/%s', 'foo'); }); |
| 134 | + }, 'unregisterProtocolHandler: Attempting to override the "' + scheme + '" protocol should throw SECURITY_ERR.'); |
181 | 135 | }
|
182 | 136 |
|
183 | 137 | /* The following protocols must be possible to override.
|
184 | 138 | * We're just testing that the call goes through here. Whether or not they
|
185 | 139 | * actually work as handlers is covered by the interactive tests. */
|
186 |
| -var whitelist = new Array( |
| 140 | + |
| 141 | +const safelist = [ |
| 142 | + /* safelisted schemes listed in |
| 143 | + * https://html.spec.whatwg.org/multipage/system-state.html#safelisted-scheme */ |
| 144 | + 'bitcoin', |
187 | 145 | 'geo',
|
188 | 146 | 'im',
|
189 | 147 | 'irc',
|
190 | 148 | 'ircs',
|
| 149 | + 'magnet', |
191 | 150 | 'mailto',
|
192 | 151 | 'mms',
|
193 | 152 | 'news',
|
194 | 153 | 'nntp',
|
| 154 | + 'openpgp4fpr', |
| 155 | + 'sip', |
195 | 156 | 'sms',
|
196 | 157 | 'smsto',
|
| 158 | + 'ssh', |
197 | 159 | 'tel',
|
198 | 160 | 'urn',
|
199 | 161 | 'webcal',
|
200 | 162 | 'wtai',
|
201 |
| - 'xmpp'); |
202 |
| - |
203 |
| -for ( var wi=0, wl=whitelist.length; wi<wl; ++wi ){ |
204 |
| - |
205 |
| - test(function () { |
206 |
| - navigator.registerProtocolHandler(whitelist[wi], location.href + '/%s', 'foo'); |
207 |
| - assert_true(true); |
208 |
| - }, 'overriding the ' + whitelist[wi] + ' protocol should work'); |
209 |
| - |
| 163 | + 'xmpp', |
| 164 | + /*other vaild schemes*/ |
| 165 | + 'BitcoIn', |
| 166 | + 'Irc', |
| 167 | + 'MagneT', |
| 168 | + 'SmsTo', |
| 169 | + 'TEL', |
| 170 | + 'teL', |
| 171 | + 'WebCAL', |
| 172 | + 'WTAI', |
| 173 | + 'web+myprotocol', |
| 174 | +]; |
| 175 | +for (const scheme of safelist) { |
| 176 | + test(() => { |
| 177 | + navigator.registerProtocolHandler(scheme, location.href + '/%s', "foo"); |
| 178 | + }, 'registerProtocolHandler: overriding the "' + scheme + '" protocol should work'); |
| 179 | + |
| 180 | + test(() => { |
| 181 | + navigator.unregisterProtocolHandler(scheme, location.href + '/%s'); |
| 182 | + }, 'unregisterProtocolHandler: overriding the "' + scheme + '" protocol should work'); |
210 | 183 | }
|
211 | 184 | </script>
|
212 |
| - |
213 |
| -</body> |
214 |
| -</html> |
0 commit comments