tor-browser

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

web-lock.tentative.https.window.js (3047B)


      1 // META: script=/common/get-host-info.sub.js
      2 // META: script=/common/utils.js
      3 // META: script=/common/dispatcher/dispatcher.js
      4 // META: script=/html/cross-origin-embedder-policy/credentialless/resources/common.js
      5 // META: script=./resources/common.js
      6 
      7 // A script acquiring a lock. It can be released using window.releaseLocks
      8 const acquire_script = (key, response) =>  `
      9  window.releaseLocks ||= [];
     10  navigator.locks.request("${key}", async lock => {
     11    send("${response}", "locked")
     12    await new Promise(r => releaseLocks.push(r));
     13    send("${response}", "unlocked");
     14  });
     15 `;
     16 
     17 const release_script = (response) => `
     18  for (release of releaseLocks)
     19    release();
     20 `;
     21 
     22 // Assert that |context| holds |expected_keys|.
     23 const assertHeldKeys = async (context, expected_keys) => {
     24  const queue = token();
     25  send(context, `
     26    const list = await navigator.locks.query();
     27    send("${queue}", JSON.stringify(list));
     28  `);
     29  const state = JSON.parse(await receive(queue));
     30  const held = state.held.map(x => x.name);
     31  assert_equals(held.length, expected_keys.length);
     32  assert_array_equals(held.sort(), expected_keys.sort());
     33 }
     34 
     35 promise_test(async test => {
     36  const origin = get_host_info().HTTPS_REMOTE_ORIGIN;
     37  const key_1 = token();
     38  const key_2 = token();
     39 
     40  // 2 actors: A credentialless iframe and a normal one.
     41  const iframe_credentialless = newIframeCredentialless(origin);
     42  const iframe_normal = newIframe(origin);
     43  const response_queue_1 = token();
     44  const response_queue_2 = token();
     45 
     46  // 1. Hold two different locks on both sides.
     47  send(iframe_credentialless, acquire_script(key_1, response_queue_1));
     48  send(iframe_normal, acquire_script(key_2, response_queue_2));
     49  assert_equals(await receive(response_queue_1), "locked");
     50  assert_equals(await receive(response_queue_2), "locked");
     51  await assertHeldKeys(iframe_credentialless, [key_1]);
     52  await assertHeldKeys(iframe_normal, [key_2]);
     53 
     54  // 2. Try to acquire the lock with the same key on the opposite side. It
     55  //    shouldn't block, because they are partitioned.
     56  send(iframe_credentialless , acquire_script(key_2, response_queue_1));
     57  send(iframe_normal, acquire_script(key_1, response_queue_2));
     58  assert_equals(await receive(response_queue_1), "locked");
     59  assert_equals(await receive(response_queue_2), "locked");
     60  await assertHeldKeys(iframe_credentialless, [key_1, key_2]);
     61  await assertHeldKeys(iframe_normal, [key_1, key_2]);
     62 
     63  // 3. Cleanup: release the 4 locks (2 on each sides).
     64  send(iframe_credentialless, release_script(response_queue_1));
     65  assert_equals(await receive(response_queue_1), "unlocked");
     66  assert_equals(await receive(response_queue_1), "unlocked");
     67  await assertHeldKeys(iframe_credentialless, []);
     68  await assertHeldKeys(iframe_normal, [key_1, key_2]);
     69 
     70  send(iframe_normal, release_script(response_queue_2));
     71  assert_equals(await receive(response_queue_2), "unlocked");
     72  assert_equals(await receive(response_queue_2), "unlocked");
     73  await assertHeldKeys(iframe_credentialless, []);
     74  await assertHeldKeys(iframe_normal, []);
     75 })