tor-browser

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

test_postMessage_special.xhtml (8113B)


      1 <!DOCTYPE html>
      2 <html xmlns="http://www.w3.org/1999/xhtml">
      3 <!--
      4 https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage
      5 -->
      6 <head>
      7  <title>postMessage from about:blank, data URLs</title>
      8  <script src="/tests/SimpleTest/SimpleTest.js"></script>        
      9  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
     10 </head>
     11 <body>
     12 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage">Mozilla Bug 387706</a>
     13 <p id="display"></p>
     14 <div id="content" style="display: none"></div>
     15 
     16 <pre id="test">
     17 <script class="testbody" type="application/javascript"><![CDATA[
     18 /** Test for Bug 387706 */
     19 
     20 SimpleTest.waitForExplicitFinish();
     21 
     22 var B64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     23 
     24 /**
     25 * Encodes an array of bytes into a string using the base 64 encoding scheme.
     26 *
     27 * @param bytes
     28 *   An array of bytes to encode.
     29 */
     30 function b64(str)
     31 {
     32  var byteArray = new Array(str.length);
     33  for (var i = 0, sz = str.length; i < sz; i++)
     34    byteArray[i] = str.charCodeAt(i);
     35 
     36  var index = 0;
     37  function get3Bytes()
     38  {
     39    if (byteArray.length - index < 3)
     40      return null; // Less than three bytes remaining
     41 
     42    // Return the next three bytes in the array, and increment index for our
     43    // next invocation
     44    return byteArray.slice(index, index += 3);
     45  }
     46 
     47  var out = "";
     48  var bytes = null;
     49  while ((bytes = get3Bytes()))
     50  {
     51    var bits = 0;
     52    for (var i = 0; i < 3; i++)
     53      bits = (bits << 8) | bytes[i];
     54    for (var j = 18; j >= 0; j -= 6)
     55      out += B64_CHARS[(bits>>j) & 0x3F];
     56  }
     57 
     58  // Get the remaining bytes
     59  bytes = byteArray.slice(index);
     60 
     61  switch (bytes.length)
     62  {
     63    case 2:
     64      out += B64_CHARS[(bytes[0]>>2) & 0x3F] +
     65             B64_CHARS[((bytes[0] & 0x03) << 4) | ((bytes[1] >> 4) & 0x0F)] +
     66             B64_CHARS[((bytes[1] & 0x0F) << 2)] +
     67             "=";
     68      break;
     69    case 1:
     70      out += B64_CHARS[(bytes[0]>>2) & 0x3F] +
     71             B64_CHARS[(bytes[0] & 0x03) << 4] +
     72             "==";
     73      break;
     74  }
     75 
     76  return out;
     77 }
     78 
     79 
     80 var aboutBlankWindow = null;
     81 var aboutBlank2Window = null;
     82 var dataWindow = null;
     83 
     84 /** Convert a nullable string to a pretty representation */
     85 function sourceify(v)
     86 {
     87  if (typeof v == "string")
     88    return "'" + v + "'";
     89  return String(v);
     90 }
     91 
     92 /** Receives MessageEvents to this window. */
     93 function messageReceiver(evt)
     94 {
     95  // It's not clear what the security model is for data: URLs and whether they
     96  // can access their parents; WebKit denies access, while Gecko currently
     97  // allows it.  We work around this problem by using postMessage (surprise!)
     98  // to start the round of tests when each iframe loads.
     99  if (evt.data === "next-test")
    100  {
    101    setTimeout(nextTest, 0);
    102    return;
    103  }
    104 
    105 
    106  try
    107  {
    108    ok(evt instanceof MessageEvent, "umm, how did we get this?");
    109    is(evt.type, "message", "expected events of type 'message'");
    110    ok(evt.isTrusted === true, "should have been a trusted event");
    111  
    112    if (evt.data === "about:blank-response")
    113    {
    114      // This isn't clarified in HTML5 yet, but the origin for a document which
    115      // has been open()ed is the origin of the calling code, somewhat loosely
    116      // speaking.  For the specific case of about:blank it's also possible
    117      // that the origin is determined by the code that opens the window.  It's
    118      // not codified yet which of these two causes the identifier tokens on
    119      // the event generated by the new window to be those of this window, but
    120      // in either case this is what they should be.
    121      is(evt.origin, "http://mochi.test:8888",
    122         "wrong origin for event from about:blank");
    123      is(evt.source, aboutBlankWindow, "wrong source");
    124 
    125      // ...and onto the next test
    126      setupBlank2();
    127    }
    128    else if (evt.data === "about:blank2-response")
    129    {
    130      is(evt.origin, "http://mochi.test:8888",
    131         "wrong origin for event from about:blank #2");
    132      is(evt.source, aboutBlank2Window, "wrong source");
    133 
    134      setupData();
    135    }
    136    else if (evt.data === "data-response")
    137    {
    138      is(evt.origin, "null",
    139         "wrong origin for event from data URL (should be the origin of the " +
    140         "window/script that opened the URL, in this case the origin of this " +
    141         "file)");
    142      is(evt.source, dataWindow, "wrong source");
    143 
    144      finish();
    145    }
    146    else
    147    {
    148      ok(false, "unexpected message: " + evt.data);
    149    }
    150  }
    151  catch (e)
    152  {
    153    ok(false, "error processing event with data '" + evt.data + "': " + e);
    154  }
    155 }
    156 
    157 function getContents(description, responseText)
    158 {
    159  var contents =
    160    "<!DOCTYPE html>\n" +
    161    "<html>\n" +
    162    "<head>\n" + 
    163    "  <title>about:blank</title>\n" +
    164    "  <script type='application/javascript'>\n" +
    165    "function receive(evt)\n" +
    166    "{\n" +
    167    "  var response = '" + responseText + "';\n" +
    168    "\n" +
    169    "  if (evt.source !== window.parent)\n" +
    170    "    response += ' wrong-source';\n" +
    171    "  if (evt.origin !== 'http://mochi.test:8888')\n" +
    172    "    response += ' wrong-origin(' + evt.origin + ')';\n" +
    173    "  if (evt.data !== 'from-opener')\n" +
    174    "    response += ' wrong-data(' + evt.data + ')';\n" +
    175    "\n" +
    176    "  window.parent.postMessage(response, 'http://mochi.test:8888');\n" +
    177    "}\n" +
    178    "\n" +
    179    "function ready()\n" +
    180    "{\n" +
    181    "  window.parent.postMessage('next-test', 'http://mochi.test:8888');\n" +
    182    "}\n" +
    183    "\n" +
    184    "window.addEventListener('load', ready, false);\n" +
    185    "window.addEventListener('message', receive, false);\n" +
    186    "  </script>\n" +
    187    "</head>\n" +
    188    "<body><p>" + description + "</p></body>\n" +
    189    "</html>";
    190 
    191  return contents;
    192 }
    193 
    194 function finish()
    195 {
    196  SimpleTest.finish();
    197 }
    198 
    199 var xhtmlns = "http://www.w3.org/1999/xhtml";
    200 
    201 function insert(el)
    202 {
    203  var content = $("content");
    204  content.parentNode.insertBefore(el, content);
    205 }
    206 
    207 function setupBlank()
    208 {
    209  var aboutBlankFrame = document.createElementNS(xhtmlns, "iframe");
    210  aboutBlankFrame.setAttribute("src", "about:blank");
    211  insert(aboutBlankFrame);
    212 
    213  aboutBlankWindow = aboutBlankFrame.contentWindow;
    214  var doc = aboutBlankWindow.document;
    215  doc.open();
    216  doc.write(getContents("This was about:blank #1", "about:blank-response"));
    217  doc.close();
    218 
    219  // I don't believe anything guarantees sync parsing, so we have to wait for
    220  // the new window to poke us to actually do the test.  :-\
    221 }
    222 
    223 function setupBlank2()
    224 {
    225  var aboutBlank2Frame = document.createElementNS(xhtmlns, "iframe");
    226  aboutBlank2Frame.addEventListener("load", nextTest);
    227  aboutBlank2Frame.setAttribute("src", "about:blank");
    228 
    229  insert(aboutBlank2Frame);
    230 }
    231 
    232 // Could use window.btoa here, but that's not standardized, and we want to be
    233 // able to run these tests against browsers that don't support it.
    234 var dataURI = "data:text/html;base64," +
    235              b64(getContents("A data: URL", "data-response"));
    236 
    237 function setupData()
    238 {
    239  var dataFrame = document.createElementNS(xhtmlns, "iframe");
    240  dataFrame.setAttribute("src", dataURI);
    241  insert(dataFrame);
    242 
    243  dataWindow = dataFrame.contentWindow;
    244 
    245  // ...and wait again for the window to load...
    246 }
    247 
    248 var count = 0;
    249 function nextTest()
    250 {
    251  switch (count++)
    252  {
    253    case 0:
    254      testBlank();
    255      break;
    256 
    257    case 1:
    258      testBlank2();
    259      break;
    260 
    261    case 2:
    262      testData();
    263      break;
    264 
    265    default:
    266      ok(false, "unreached");
    267      break;
    268  }
    269 }
    270 
    271 function testBlank()
    272 {
    273  aboutBlankWindow.postMessage("from-opener", "http://mochi.test:8888");
    274 }
    275 
    276 function testBlank2()
    277 {
    278  // For some reason we can't access this across browsers prior to the iframe
    279  // loading, so set its value here.
    280  aboutBlank2Window = window.frames[1];
    281 
    282  var doc = aboutBlank2Window.document;
    283 
    284  doc.body.textContent = "This was about:blank #2";
    285 
    286  var script = doc.createElement("script");
    287  script.textContent =
    288    "window.parent.postMessage('about:blank2-response', " +
    289    "                          'http://mochi.test:8888');";
    290  doc.body.appendChild(script);
    291 }
    292 
    293 function testData()
    294 {
    295  dataWindow.postMessage("from-opener", "*");
    296 }
    297 
    298 window.addEventListener("message", messageReceiver);
    299 
    300 addLoadEvent(setupBlank);
    301 ]]></script>
    302 </pre>
    303 </body>
    304 </html>