Bug 1264573 - Blob url isolation tests, adapted from Tor Browser patch 15502. r=baku, r=arthuredelstein
☠☠ backed out by 160a02f0a460 ☠ ☠
authorJonathan Hao <jhao@mozilla.com>
Fri, 02 Sep 2016 00:32:00 -0400
changeset 312420 4dfb2d13513f7955a7ee7da6eb37eae0bd5d3df3
parent 312419 8103fef19cbb60df33c0085d2e91d6a83d68ae43
child 312421 e6cd5070f45402ae11b0d16dc42fcf2db7d557ef
push id20447
push userkwierso@gmail.com
push dateFri, 02 Sep 2016 20:36:44 +0000
treeherderfx-team@969397f22187 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku, arthuredelstein
bugs1264573, 15502
milestone51.0a1
Bug 1264573 - Blob url isolation tests, adapted from Tor Browser patch 15502. r=baku, r=arthuredelstein
browser/components/originattributes/test/browser/browser.ini
browser/components/originattributes/test/browser/browser_blobURLIsolation.js
browser/components/originattributes/test/browser/worker_blobify.js
browser/components/originattributes/test/browser/worker_deblobify.js
--- a/browser/components/originattributes/test/browser/browser.ini
+++ b/browser/components/originattributes/test/browser/browser.ini
@@ -14,11 +14,14 @@ support-files =
   test_firstParty.html
   test_firstParty_cookie.html
   test_firstParty_html_redirect.html
   test_firstParty_http_redirect.html
   test_firstParty_http_redirect.html^headers^
   test_firstParty_iframe_http_redirect.html
   test_firstParty_postMessage.html
   window.html
+  worker_blobify.js
+  worker_deblobify.js
 
+[browser_blobURLIsolation.js]
 [browser_firstPartyIsolation.js]
 [browser_localStorageIsolation.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/browser_blobURLIsolation.js
@@ -0,0 +1,94 @@
+/**
+ * Bug 1264573 - A test case for blob url isolation.
+ */
+
+const TEST_PAGE = "http://mochi.test:8888/browser/browser/components/" +
+                  "originattributes/test/browser/file_firstPartyBasic.html";
+const SCRIPT_WORKER_BLOBIFY = "worker_blobify.js";
+const SCRIPT_WORKER_DEBLOBIFY = "worker_deblobify.js";
+
+function page_blobify(browser, input) {
+  return ContentTask.spawn(browser, input, function(input) {
+    return { blobURL: content.URL.createObjectURL(new content.Blob([input])) };
+  });
+}
+
+function page_deblobify(browser, blobURL) {
+  return ContentTask.spawn(browser, blobURL, function* (blobURL) {
+    if ("error" in blobURL) {
+      return blobURL;
+    }
+    blobURL = blobURL.blobURL;
+
+    function blobURLtoBlob(blobURL) {
+      return new content.Promise(function (resolve) {
+        let xhr = new content.XMLHttpRequest();
+        xhr.open("GET", blobURL, true);
+        xhr.onload = function () {
+          resolve(xhr.response);
+        };
+        xhr.onerror = function () {
+          resolve("xhr error");
+        };
+        xhr.responseType = "blob";
+        xhr.send();
+      });
+    }
+
+    function blobToString(blob) {
+      return new content.Promise(function (resolve) {
+        let fileReader = new content.FileReader();
+        fileReader.onload = function () {
+          resolve(fileReader.result);
+        };
+        fileReader.readAsText(blob);
+      });
+    }
+
+    let blob = yield blobURLtoBlob(blobURL);
+    if (blob == "xhr error") {
+      return "xhr error";
+    }
+
+    return yield blobToString(blob);
+  });
+}
+
+function workerIO(browser, scriptFile, message) {
+  return ContentTask.spawn(browser, {scriptFile, message}, function* (args) {
+    let worker = new content.Worker(args.scriptFile);
+    let promise = new content.Promise(function(resolve) {
+      let listenFunction = function(event) {
+        worker.removeEventListener("message", listenFunction, false);
+        worker.terminate();
+        resolve(event.data);
+      };
+      worker.addEventListener("message", listenFunction, false);
+    });
+    worker.postMessage(args.message);
+    return yield promise;
+  });
+}
+
+let worker_blobify = (browser, input) => workerIO(browser, SCRIPT_WORKER_BLOBIFY, input);
+let worker_deblobify = (browser, blobURL) => workerIO(browser, SCRIPT_WORKER_DEBLOBIFY, blobURL);
+
+let blobURL = null;
+function doTest(blobify, deblobify) {
+  return function* (browser, tabNum) {
+    if (blobURL === null) {
+      let input = Math.random().toString();
+      blobURL = yield blobify(browser, input);
+      return input;
+    }
+    let result = yield deblobify(browser, blobURL);
+    blobURL = null;
+    return result;
+  }
+}
+
+for (let blobify of [page_blobify, worker_blobify]) {
+  for (let deblobify of [page_deblobify, worker_deblobify]) {
+    IsolationTestTools.runTests(TEST_PAGE, doTest(blobify, deblobify));
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/worker_blobify.js
@@ -0,0 +1,11 @@
+// Wait for a string to be posted to this worker.
+// Create a blob containing this string, and then
+// post back a blob URL pointing to the blob.
+self.addEventListener("message", function (e) {
+  try {
+    var blobURL = URL.createObjectURL(new Blob([e.data]));
+    postMessage({ blobURL });
+  } catch (e) {
+    postMessage({ error: e.message });
+  }
+}, false);
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/worker_deblobify.js
@@ -0,0 +1,31 @@
+// Wait for a blob URL to be posted to this worker.
+// Obtain the blob, and read the string contained in it.
+// Post back the string.
+
+var postStringInBlob = function (blobObject) {
+  var fileReader = new FileReaderSync();
+  var result = fileReader.readAsText(blobObject);
+  postMessage(result);
+};
+
+self.addEventListener("message", function (e) {
+  if ("error" in e.data) {
+    postMessage(e.data);
+    return;
+  }
+  var blobURL = e.data.blobURL,
+      xhr = new XMLHttpRequest();
+  try {
+    xhr.open("GET", blobURL, true);
+    xhr.onload = function () {
+      postStringInBlob(xhr.response);
+    };
+    xhr.onerror = function () {
+      postMessage({ error: "xhr error" });
+    };
+    xhr.responseType = "blob";
+    xhr.send();
+  } catch (e) {
+    postMessage({ error: e.message });
+  }
+}, false);