FileSystemBaseHandle-postMessage-Error.js (10192B)
1 'use strict'; 2 3 // This script depends on the following scripts: 4 // /fs/resources/messaging-helpers.js 5 // /fs/resources/messaging-blob-helpers.js 6 // /fs/resources/messaging-serialize-helpers.js 7 // /fs/resources/test-helpers.js 8 // /common/get-host-info.sub.js 9 // /service-workers/service-worker/resources/test-helpers.sub.js 10 11 // Define URL constants for cross origin windows. 12 const kRemoteOrigin = get_host_info().HTTPS_REMOTE_ORIGIN; 13 const kRemoteOriginDocumentMessageTarget = `${kRemoteOrigin}${base_path()}` + 14 kDocumentMessageTarget; 15 16 // Sending a FileSystemHandle to a cross origin |target| through postMessage() 17 // must dispatch the 'messageerror' event. 18 // 19 // This test sends a FileSystemHandle to |target|. |target| responds with a 20 // serialized MessageEvent from the 'messageerror' event, allowing the test 21 // runner to verify MessageEvent properties. 22 async function do_send_message_error_test( 23 test, 24 root_dir, 25 receiver, 26 target, 27 target_origin, 28 // False when the MessageEvent's source is null. 29 expected_has_source, 30 // The origin of MessageEvents received by |target|. 31 expected_origin) { 32 const message_watcher = new EventWatcher(test, receiver, 'message'); 33 34 // Send a file to |target|. 35 const file = await createFileWithContents( 36 'test-error-file', 'test-error-file-contents', root_dir); 37 target.postMessage( 38 { type: 'receive-file-system-handles', cloned_file_system_handles: [file] }, 39 { targetOrigin: target_origin }); 40 41 // Wait for |target| to respond with results. 42 let message_event = await message_watcher.wait_for('message'); 43 const first_response = message_event.data; 44 assert_equals(first_response.type, 'serialized-message-error', 45 'The test runner must receive a "serialized-message-error" message ' + 46 'in response to a FileSystemFileHandle message.'); 47 48 // Verify the results. 49 assert_equals_serialized_message_error_event( 50 first_response.serialized_message_error_event, 51 expected_origin, expected_has_source); 52 53 // Send a directory to |target|. 54 const directory = await createDirectory('test-error-directory', root_dir); 55 56 target.postMessage( 57 { 58 type: 'receive-file-system-handles', 59 cloned_file_system_handles: [directory] 60 }, { targetOrigin: target_origin }); 61 62 // Wait for |target| to respond with results. 63 message_event = await message_watcher.wait_for('message'); 64 const second_response = message_event.data; 65 assert_equals(second_response.type, 'serialized-message-error', 66 'The test runner must receive a "serialized-message-error" message ' + 67 'response to a FileSystemDirectoryHandle message.'); 68 69 // Verify the results. 70 assert_equals_serialized_message_error_event( 71 second_response.serialized_message_error_event, 72 expected_origin, expected_has_source); 73 } 74 75 // This test receives a FileSystemHandle from |target|. This test runner 76 // must dispatch the 'messageerror' event after receiving a handle from target. 77 async function do_receive_message_error_test( 78 test, 79 receiver, 80 target, 81 target_origin, 82 // False when the MessageEvent's source is null. 83 expected_has_source, 84 // The origin of MessageEvents received by this test runner. 85 expected_origin) { 86 const error_watcher = new EventWatcher(test, receiver, 'messageerror'); 87 88 // Receive a file from |target|. 89 target.postMessage( 90 { type: 'create-file' }, { targetOrigin: target_origin }); 91 const first_error = await error_watcher.wait_for('messageerror'); 92 const serialized_first_error = serialize_message_error_event(first_error); 93 assert_equals_serialized_message_error_event( 94 serialized_first_error, expected_origin, expected_has_source); 95 96 // Receive a directory from |target|. 97 target.postMessage( 98 { type: 'create-directory' }, { targetOrigin: target_origin }); 99 const second_error = await error_watcher.wait_for('messageerror'); 100 const serialized_second_error = serialize_message_error_event(second_error); 101 assert_equals_serialized_message_error_event( 102 serialized_second_error, expected_origin, expected_has_source); 103 } 104 105 // Performs the send message error test followed by the receive message error 106 // test. 107 async function do_send_and_receive_message_error_test( 108 test, 109 root_dir, 110 receiver, 111 target, 112 target_origin, 113 // False when the MessageEvent's source is null. 114 expected_has_source, 115 // The origin of MessageEvents received by |target|. 116 expected_origin, 117 // The origin of MessageEvents received by this test runner. 118 expected_remote_origin) { 119 await do_send_message_error_test( 120 test, root_dir, receiver, target, target_origin, expected_has_source, 121 expected_origin); 122 await do_receive_message_error_test( 123 test, receiver, target, target_origin, expected_has_source, 124 expected_remote_origin); 125 } 126 127 // Runs the same test as do_send_message_error_test(), but uses a MessagePort. 128 // This test starts by establishing a message channel between the test runner 129 // and |target|. 130 async function do_send_message_port_error_test( 131 test, root_dir, target, target_origin) { 132 const message_port = create_message_channel(target, target_origin); 133 await do_send_message_error_test( 134 test, root_dir, /*receiver=*/message_port, /*target=*/message_port, 135 /*target_origin=*/undefined, /*expected_has_source=*/false, 136 /*expected_origin=*/'', /*expected_remote_origin=*/''); 137 } 138 139 // Runs the same test as do_receive_message_error_test(), but uses a MessagePort. 140 async function do_receive_message_port_error_test( 141 test, target, target_origin) { 142 const message_port = create_message_channel(target, target_origin); 143 await do_receive_message_error_test( 144 test, /*receiver=*/message_port, /*target=*/message_port, 145 /*target_origin=*/undefined, /*expected_has_source=*/false, 146 /*expected_origin=*/''); 147 } 148 149 // Runs the same test as do_send_and_receive_message_error_test(), but uses a 150 // MessagePort. 151 async function do_send_and_receive_message_port_error_test( 152 test, root_dir, target, target_origin) { 153 await do_send_message_port_error_test( 154 test, root_dir, target, target_origin); 155 await do_receive_message_port_error_test( 156 test, target, target_origin); 157 } 158 159 directory_test(async (t, root_dir) => { 160 const iframe = await add_iframe( 161 t, { src: kRemoteOriginDocumentMessageTarget }); 162 await do_send_and_receive_message_error_test( 163 t, root_dir, /*receiver=*/self, /*target=*/iframe.contentWindow, 164 /*target_origin=*/'*', /*expected_has_source=*/true, 165 /*expected_origin=*/location.origin, 166 /*expected_remote_origin=*/kRemoteOrigin); 167 }, 'Fail to send and receive messages using a cross origin iframe.'); 168 169 directory_test(async (t, root_dir) => { 170 const iframe = await add_iframe(t, { src: kRemoteOriginDocumentMessageTarget }); 171 await do_send_and_receive_message_port_error_test( 172 t, root_dir, /*target=*/iframe.contentWindow, /*target_origin=*/'*'); 173 }, 'Fail to send and receive messages using a cross origin message port in ' + 174 'an iframe.'); 175 176 directory_test(async (t, root_dir) => { 177 const iframe = await add_iframe( 178 t, { src: kDocumentMessageTarget, sandbox: 'allow-scripts' }); 179 180 await do_send_message_error_test( 181 t, root_dir, /*receiver=*/self, /*target=*/iframe.contentWindow, 182 /*target_origin=*/'*', /*expected_has_source*/true, 183 /*expected_origin=*/location.origin); 184 }, 'Fail to send to a sandboxed iframe.'); 185 186 directory_test(async (t, root_dir) => { 187 const iframe = await add_iframe( 188 t, { src: kDocumentMessageTarget, sandbox: 'allow-scripts' }); 189 await do_send_message_port_error_test( 190 t, root_dir, /*target=*/iframe.contentWindow, /*target_origin=*/'*'); 191 }, 'Fail to send messages using a message port to a sandboxed ' + 192 'iframe.'); 193 194 directory_test(async (t, root_dir) => { 195 const iframe_data_uri = await create_message_target_data_uri(t); 196 const iframe = await add_iframe(t, { src: iframe_data_uri }); 197 await do_send_message_error_test(t, root_dir, /*receiver=*/self, 198 /*target=*/iframe.contentWindow, /*target_origin=*/'*', 199 /*expected_has_source*/true, /*expected_origin=*/location.origin); 200 // Do not test receiving FileSystemHandles from the data URI iframe. Data URI 201 // iframes are insecure and do not expose the File System APIs. 202 }, 'Fail to send messages to a data URI iframe.'); 203 204 directory_test(async (t, root_dir) => { 205 const iframe_data_uri = await create_message_target_data_uri(t); 206 const iframe = await add_iframe(t, { src: iframe_data_uri }); 207 await do_send_message_port_error_test( 208 t, root_dir, /*target=*/iframe.contentWindow, /*target_origin=*/'*'); 209 }, 'Fail to send messages using a message port in a data URI iframe.'); 210 211 directory_test(async (t, root_dir) => { 212 const child_window = await open_window(t, kRemoteOriginDocumentMessageTarget); 213 await do_send_and_receive_message_error_test( 214 t, root_dir, /*receiver=*/self, /*target=*/child_window, /*target_origin=*/'*', 215 /*expected_has_source=*/true, /*expected_origin=*/location.origin, 216 /*expected_remote_origin=*/kRemoteOrigin); 217 }, 'Fail to send and receive messages using a cross origin window.'); 218 219 directory_test(async (t, root_dir) => { 220 const child_window = await open_window(t, kRemoteOriginDocumentMessageTarget); 221 await do_send_message_port_error_test( 222 t, root_dir, /*target=*/child_window, /*target_origin=*/'*'); 223 }, 'Fail to send and receive messages using a cross origin message port in ' + 224 'a window.'); 225 226 directory_test(async (t, root_dir) => { 227 const url = `${kDocumentMessageTarget}?pipe=header(Content-Security-Policy` + 228 ', sandbox allow-scripts)'; 229 const child_window = await open_window(t, url); 230 await do_send_message_error_test( 231 t, root_dir, /*receiver=*/self, /*target=*/child_window, 232 /*target_origin=*/'*', /*expected_has_source*/true, 233 /*expected_origin=*/location.origin); 234 }, 'Fail to send messages to a sandboxed window.'); 235 236 directory_test(async (t, root_dir) => { 237 const url = `${kDocumentMessageTarget}?pipe=header(Content-Security-Policy` + 238 ', sandbox allow-scripts)'; 239 const child_window = await open_window(t, url); 240 await do_send_message_port_error_test( 241 t, root_dir, /*target=*/child_window, /*target_origin=*/'*'); 242 }, 'Fail to send messages using a message port to a sandboxed ' + 243 'window.');