tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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.');