tor-browser

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

opaque-origin.html (7138B)


      1 <!doctype html>
      2 <html>
      3 <head>
      4 <meta charset=utf-8>
      5 <meta name="timeout" content="long">
      6 <title></title>
      7 <script src=/resources/testharness.js></script>
      8 <script src=/resources/testharnessreport.js></script>
      9 </head>
     10 <body>
     11 <script>
     12 <!--
     13 promise_test(t => {
     14  return new Promise((resolve) => {
     15    let ifr = document.createElement("iframe");
     16    ifr.src =
     17      "data:text/html,<script> let bc = new BroadcastChannel(\"test\");" +
     18      "bc.onmessage = (e) => {" +
     19      "  if (e.data == \"ping\") bc.postMessage('pong');"+
     20      "  else parent.postMessage({workerMessageOrigin: e.data, messageOrigin: e.origin}, \"*\"); };" +
     21      "new Worker(URL.createObjectURL(new Blob([\"" +
     22      "let bc2 = new BroadcastChannel('test'); bc2.postMessage('ping'); " +
     23      "bc2.onmessage = e => bc2.postMessage(e.origin);" +
     24      "\"], {type: 'text/javascript'}))); </script>";
     25    window.addEventListener("message", t.step_func(e => {
     26        assert_equals(e.data.workerMessageOrigin, "null");
     27        assert_equals(e.data.messageOrigin, "null");
     28        resolve();
     29      }), {once: true});
     30    t.add_cleanup(() => { document.body.removeChild(ifr) });
     31    document.body.appendChild(ifr);
     32    });
     33 }, "Opaque origin should be serialized to \"null\"");
     34 
     35 
     36 const iframe_src = (channel_name, iframe_name) => `data:text/html,<script>
     37 let bc2 = new BroadcastChannel("${channel_name}");
     38 bc2.onmessage = (e) => {
     39  if (e.data == "from-${iframe_name}") {
     40    parent.postMessage("${iframe_name}-done", "*");
     41  } else {
     42    parent.postMessage("fail", "*");
     43  }
     44 };
     45 let bc3 = new BroadcastChannel("${channel_name}");
     46 bc3.postMessage("from-${iframe_name}");
     47 </script>`;
     48 
     49 promise_test(t => {
     50  return new Promise((resolve, reject) => {
     51    const channel_name = "opaque-origin-test-2";
     52    const bc1 = new BroadcastChannel(channel_name);
     53    bc1.onmessage = t.unreached_func("Received message from an opaque origin");
     54 
     55    // We'll create an iframe and have it send a BroadcastChannel message
     56    // between two instances. Once the message is received, it will postMessage
     57    // back and we'll repeat this with another iframe. If the first
     58    // BroadcastChannel message is received by `bc1`, or if the second
     59    // BroadcastChannel message is received by `bc1` or `bc2` in the first
     60    // iframe, then the test should fail.
     61 
     62    window.addEventListener("message", e => {
     63      if(e.data == "iframe1-done") {
     64        let iframe2 = document.createElement("iframe");
     65        iframe2.src = iframe_src(channel_name, "iframe2");
     66        t.add_cleanup(() => { document.body.removeChild(iframe2) });
     67        document.body.appendChild(iframe2);
     68      } else if(e.data == "iframe2-done") {
     69        resolve();
     70      } else if(e.data == "fail") {
     71        reject("One opaque origin received a message from the other");
     72      } else {
     73        reject("An unexpected error occurred");
     74      }
     75    });
     76 
     77    let iframe1 = document.createElement("iframe");
     78    iframe1.src = iframe_src(channel_name, "iframe1");
     79    t.add_cleanup(() => { document.body.removeChild(iframe1) });
     80    document.body.appendChild(iframe1);
     81    });
     82 }, "BroadcastChannel messages from opaque origins should be self-contained");
     83 
     84 const data_url_worker_src = (channel_name, worker_name) => {
     85  const source = `
     86 const handler = (reply) => {
     87  let bc2 = new BroadcastChannel("${channel_name}");
     88  bc2.onmessage = (e) => {
     89    if (e.data == "from-${worker_name}") {
     90      reply("${worker_name}-done");
     91    } else {
     92      reply("fail");
     93    }
     94  };
     95  let bc3 = new BroadcastChannel("${channel_name}");
     96  bc3.postMessage("from-${worker_name}");
     97 };
     98 // For dedicated workers:
     99 self.addEventListener("message", () => handler(self.postMessage));
    100 // For shared workers:
    101 self.addEventListener("connect", (e) => {
    102  var port = e.ports[0];
    103  port.onmessage = () => handler(msg => port.postMessage(msg));
    104  port.start();
    105 
    106 });
    107 `;
    108  return "data:,".concat(encodeURIComponent(source));
    109 }
    110 
    111 promise_test(t => {
    112  return new Promise((resolve, reject) => {
    113    const channel_name = "opaque-origin-test-3";
    114    const bc1 = new BroadcastChannel(channel_name);
    115    bc1.onmessage = e => { reject("Received message from an opaque origin"); };
    116 
    117    // Same as the previous test but with data URL dedicated workers (which
    118    // should have opaque origins per the HTML spec).
    119    const worker_name_prefix = "data-url-dedicated-worker";
    120    const worker_1_name = `${worker_name_prefix}-1`;
    121    const worker_2_name = `${worker_name_prefix}-2`;
    122 
    123    const handler = e => {
    124      if(e.data == `${worker_1_name}-done`) {
    125        const worker2 = new Worker(data_url_worker_src(channel_name, worker_2_name));
    126        t.add_cleanup(() => worker2.terminate());
    127        worker2.addEventListener("message", handler);
    128        worker2.postMessage("go!");
    129      } else if(e.data == `${worker_2_name}-done`) {
    130        resolve();
    131      } else if(e.data == "fail") {
    132        reject("One opaque origin received a message from the other");
    133      } else {
    134        reject("An unexpected error occurred");
    135      }
    136    };
    137 
    138    let worker1 = new Worker(data_url_worker_src(channel_name, worker_1_name));
    139    t.add_cleanup(() => worker1.terminate());
    140    worker1.addEventListener("message", handler);
    141    worker1.postMessage("go!");
    142    });
    143 }, "BroadcastChannel messages from data URL dedicated workers should be self-contained");
    144 
    145 promise_test(() => {
    146  return new Promise((resolve, reject) => {
    147    const channel_name = "opaque-origin-test-4";
    148    const bc1 = new BroadcastChannel(channel_name);
    149 
    150    // Same as the previous test but with data URL shared workers (which
    151    // should have opaque origins per the HTML spec).
    152    const worker_name_prefix = "data-url-shared-worker";
    153    const worker_1_name = `${worker_name_prefix}-1`;
    154    const worker_2_name = `${worker_name_prefix}-2`;
    155 
    156    const handler = e => {
    157      if (e.data == `${worker_1_name}-done`) {
    158        const worker_script = data_url_worker_src(channel_name, worker_2_name);
    159        const worker2 = new SharedWorker(worker_script, worker_2_name);
    160        worker2.port.addEventListener("message", handler);
    161        worker2.port.start();
    162        worker2.port.postMessage("go!");
    163      } else if(e.data == `${worker_2_name}-done`) {
    164        resolve();
    165      } else if(e.data == "fail") {
    166        reject("One opaque origin received a message from the other");
    167      } else {
    168        reject("An unexpected error occurred");
    169      }
    170    };
    171 
    172    bc1.onmessage = e => {
    173      if (e.data == "go!") {
    174        const worker_script = data_url_worker_src(channel_name, worker_1_name);
    175        const worker1 = new SharedWorker(worker_script, worker_1_name);
    176        worker1.port.addEventListener("message", handler);
    177        worker1.port.start();
    178        worker1.port.postMessage("go!");
    179      } else {
    180        reject("Received message from an opaque origin");
    181      }
    182    };
    183 
    184    // Ensure that the BroadcastChannel instance above can receive messages
    185    // before we create the first shared worker.
    186    const bc2 = new BroadcastChannel(channel_name);
    187    bc2.postMessage("go!");
    188    });
    189 }, "BroadcastChannel messages from data URL shared workers should be self-contained");
    190 //-->
    191 </script>
    192 </body>
    193 </html>