Skip to content
Permalink
Browse files

fixup! Bug #15502, Part 2: Regression tests for blob URL isolation

  • Loading branch information
arthuredelstein committed Jun 22, 2015
1 parent e6d886d commit 8f1e017855789f82777a65b93f28a74f9e7d0534
@@ -6,14 +6,15 @@
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Page blobifier for Tor Browser Bug 15502</title>
<script type="text/javascript;version=1.7" src="task_spawn.js"></script>
<script type="text/javascript;version=1.7" src="bug15502_utils.js"></script>
</head>
<body>
<div id="display" style="white-space:pre; font-family:monospace; display:inline;"></div>

<script type="text/javascript;version=1.7">

Task.spawn(function* () {
spawn(function* () {
sendMessage(window.parent, "ready");
let message = yield receiveMessage(window.parent),
blobURL = stringToBlobURL(message);
@@ -6,14 +6,15 @@
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Page deblobifier for Tor Browser Bug 15502</title>
<script type="text/javascript;version=1.7" src="task_spawn.js"></script>
<script type="text/javascript;version=1.7" src="bug15502_utils.js"></script>
</head>
<body>
<div id="display" style="white-space:pre; font-family:monospace; display:inline;"></div>

<script type="text/javascript;version=1.7">

Task.spawn(function* () {
spawn(function* () {
sendMessage(window.parent, "ready");
let blobURL = yield receiveMessage(window.parent),
string;
@@ -6,6 +6,7 @@
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Tab for Tor Browser Bug 15502</title>
<script type="text/javascript;version=1.7" src="task_spawn.js"></script>
<script type="text/javascript;version=1.7" src="bug15502_utils.js"></script>
</head>
<body>
@@ -18,15 +19,15 @@
let iframe = document.getElementById("child");

let connect = function (sourceObject, destinationObject) {
Task.spawn(function* () {
spawn(function* () {
for (;;) {
let message = yield receiveMessage(sourceObject);
sendMessage(destinationObject, message);
}
});
};

Task.spawn(function* () {
spawn(function* () {
sendMessage(window.opener, "ready");
let firstParentMessage = yield receiveMessage(window.opener);
iframe.src = firstParentMessage;
@@ -1,29 +1,28 @@
// Import Task.jsm
let { Task } = SpecialPowers.Cu.import("resource://gre/modules/Task.jsm");

// __listen(target, eventType, timeoutMs, useCapture)__.
// Calls addEventListener on target, with the given eventType.
// Returns a Promise that resolves to an Event object, if the event fires.
// If a timeout occurs, then Promise is rejected with a "Timed out" error.
// For use with Task.jsm.
// For use with task_spawn.js.
let listen = function (target, eventType, timeoutMs, useCapture) {
return new Promise(function (resolve, reject) {
let listenFunction = function (event) {
target.removeEventListener(eventType, listenFunction, useCapture);
resolve(event);
};
target.addEventListener(eventType, listenFunction, useCapture);
setTimeout(() => reject(new Error("Timed out")), timeoutMs);
if (timeoutMs) {
setTimeout(() => reject(new Error("Timed out")), timeoutMs);
}
});
};

// __receiveMessage(source)__.
// Returns an event object for the next message received from source.
// A Task.jsm coroutine.
// A task_spawn.js coroutine.
let receiveMessage = function* (source) {
let event;
do {
event = yield listen(self, "message", 5000, false);
event = yield listen(self, "message", null, false);
} while (event.source !== source);
return event.data;
};
@@ -94,7 +93,7 @@ let stringToBlobURL = function (s) {
// __workerIO(scriptFile, inputString)__.
// Sends inputString for the worker, and waits
// for the worker to return an outputString.
// Task.jsm coroutine.
// task_spawn.js coroutine.
let workerIO = function* (scriptFile, inputString) {
let worker = new Worker(scriptFile);
worker.postMessage(inputString);
@@ -6,6 +6,7 @@
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Worker blobifier for Tor Browser Bug 15502</title>
<script type="text/javascript;version=1.7" src="task_spawn.js"></script>
<script type="text/javascript;version=1.7" src="bug15502_utils.js"></script>
</head>
<body>
@@ -14,7 +15,7 @@
<pre id="test">
<script type="text/javascript;version=1.7">

Task.spawn(function* () {
spawn(function* () {
sendMessage(window.parent, "ready");
let message = yield receiveMessage(window.parent),
blobURL = yield workerIO("bug15502_worker_blobify.js", message);
@@ -6,6 +6,7 @@
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Worker deblobifier for Tor Browser Bug 15502</title>
<script type="text/javascript;version=1.7" src="task_spawn.js"></script>
<script type="text/javascript;version=1.7" src="bug15502_utils.js"></script>
</head>
<body>
@@ -14,7 +15,7 @@
<pre id="test">
<script type="text/javascript;version=1.7">

Task.spawn(function* () {
spawn(function* () {
sendMessage(window.parent, "ready");
let blobURL = yield receiveMessage(window.parent),
result = yield workerIO("bug15502_worker_deblobify.js", blobURL);
@@ -244,6 +244,7 @@ support-files =
send_gzip_content.sjs
somedatas.resource
somedatas.resource^headers^
task_spawn.js
variable_style_sheet.sjs
viewport_helpers.js
w3element_traversal.svg
@@ -0,0 +1,63 @@
// # task_spawn.js
// A simple implementation of Task.spawn. For detailed usage instructions,
// see https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Task.jsm

/* jshint esnext: true */

// __spawn(generatorFunction)__.
// Expose only the spawn function, very similar to Task.spawn in Task.jsm.
let spawn = (function () {

// Declare ahead
let promiseFromGenerator;

// Returns true if aValue is a generator object.
let isGenerator = aValue => {
return Object.prototype.toString.call(aValue) === "[object Generator]";
};

// Converts the right-hand argument of yield or return values to a Promise,
// according to Task.jsm semantics.
let asPromise = yieldArgument => {
if (yieldArgument instanceof Promise) {
return yieldArgument;
} else if (isGenerator(yieldArgument)) {
return promiseFromGenerator(yieldArgument);
} else if (yieldArgument instanceof Function) {
return asPromise(yieldArgument());
} else if (yieldArgument instanceof Error) {
return Promise.reject(yieldArgument);
} else {
return Promise.resolve(yieldArgument);
}
};

// Takes a generator object and runs it as an asynchronous task,
// returning a Promise with the result of that task.
promiseFromGenerator = generator => {
return new Promise((resolve, reject) => {
let processPromise;
let processPromiseResult = (success, result) => {
try {
let {value, done} = success ? generator.next(result)
: generator.throw(result);
if (done) {
asPromise(value).then(resolve, reject);
} else {
processPromise(asPromise(value));
}
} catch (error) {
reject(error);
}
};
processPromise = promise => {
promise.then(result => processPromiseResult(true, result),
error => processPromiseResult(false, error));
};
processPromise(asPromise(undefined));
});
};

// __spawn(generatorFunction)__.
return generatorFunction => promiseFromGenerator(generatorFunction());
})();
@@ -7,6 +7,7 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Test for Tor Browser Bug 15502</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript;version=1.7" src="task_spawn.js"></script>
<script type="text/javascript;version=1.7" src="bug15502_utils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
@@ -17,8 +18,14 @@
<script class="testbody" type="application/javascript;version=1.7">
SimpleTest.waitForExplicitFinish();

// __prefs__. Import the `Serivces.prefs` object.
let prefs = SpecialPowers.Cu.import("resource://gre/modules/Services.jsm").Services.prefs;
// __setPref(key, value)__.
// Set a pref value asynchronously, returning a prmoise that resolves
// when it succeeds.
let setPref = function* (key, value) {
return new Promise(function(resolve, reject) {
SpecialPowers.pushPrefEnv({"set": [[key, value]]}, resolve);
});
};

// ## Testing constants
let domain1 = "http://example.com",
@@ -47,7 +54,7 @@
// and then attempt to retrieve the object from the blobURL in `domainB`, using
// the page `deblobPage`.
let blobTest = function* (isolationOn, domainA, domainB, blobPage, deblobPage) {
prefs.setIntPref("privacy.thirdparty.isolate", isolationOn ? 2 : 0);
yield setPref("privacy.thirdparty.isolate", isolationOn ? 2 : 0);
let input = "" + Math.random(),
blobURL = yield tabIO(domainA, blobPage, input),
result = yield tabIO(domainB, deblobPage, blobURL),
@@ -71,9 +78,9 @@


// ## The main test
// Run a Task.jsm coroutine that tests various combinations of domains
// Run a coroutine that tests various combinations of domains
// methods, and isolation states for reading and writing blob URLs.
Task.spawn(function* () {
spawn(function* () {
for (let isolate of [false, true]) {
for (let domainB of [domain1, domain2]) {
for (let blob of [page_blob, worker_blob]) {

0 comments on commit 8f1e017

Please sign in to comment.
You can’t perform that action at this time.