gecko-dev/dom/tests/mochitest/chrome/test_clonewrapper.xul
Bobby Holley 24a1e4a8e1 Bug 1050340 - Fix up cloning test. r=gabor
This test currently assume that cloning a COW will fail. Once we always go over
security wrappers, this isn't true anymore, because COWs silently deny
disallowed property gets. So it makes sense to rewrite the test so that we can
see what actually makes it through the structured clones. Promises galore.

We also take out the buggy Blob/FileList stuff and replace it with ImageData,
which does a bonafide clone in NS_DOMWriteStructuredClone instead of the weird
pointer swapping we do in nsGlobalWindow.cpp (baku is in the process of cleaning
that up, but it's not done yet).
2014-08-18 14:18:40 -07:00

127 lines
5.1 KiB
XML

<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=667388
-->
<window title="Mozilla Bug 667388"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<!-- test code goes here -->
<script type="application/javascript">
<![CDATA[
// Setup.
const Cu = Components.utils;
SimpleTest.waitForExplicitFinish();
window.testObject = { myNumber: 42,
myDomain: window.location.domain };
// Wait for both frames to load before proceeding.
var framesLoaded = [null, false, false, false];
function onFrameLoaded(id) {
// Mark this frame as loaded.
framesLoaded[id] = true;
// Allow it to call various helpers.
window.frames[id].wrappedJSObject.is = is;
window.frames[id].wrappedJSObject.ok = ok;
window.frames[id].wrappedJSObject.info = info;
// If all the frames are loaded, start the test.
if (framesLoaded[1] && framesLoaded[2] && framesLoaded[3])
startTest();
}
function reject(e) {
ok(false, "Rejected Promise: " + e);
SimpleTest.finish();
}
function startTest() {
runChromeContentTest(window.frames[1]).then(
runContentContentTest.bind(null, window.frames[1], window.frames[2],
true, "Should be able to clone same-origin"), reject).then(
runContentContentTest.bind(null, window.frames[2], window.frames[3],
false, "Should not be able to clone cross-origin"), reject).then(function() {
// Colaborate with document.domain, then try again.
frames[2].document.domain = 'example.org';
frames[3].document.domain = 'example.org';
return runContentContentTest(window.frames[2], window.frames[3],
true, "Should be able to clone cross-origin with document.domain")
}, reject).then(SimpleTest.finish.bind(SimpleTest), reject);
}
// Tests cloning between chrome and content.
function runChromeContentTest(contentWin) {
// We should be able to clone a content object.
tryToClone(contentWin.wrappedJSObject.testObject,
true,
"Chrome should be able to clone content object");
// COWs without __exposedProps__ silently deny property gets. So Content
// should be able to clone a COW, but the result of the clone should be empty.
var p = contentWin.wrappedJSObject.tryToClone(window.testObject, true,
"Content should be able to clone COW");
return new Promise(function(resolve) {
p.then(function(cloneResult) {
is(Cu.waiveXrays(cloneResult).toSource(), "({})", "Empty COW clone");
resolve();
});
});
}
// Test cloning between content and content.
//
// Note - the way we do this is kind of sketchy. Because we're grabbing the
// test object from win1 by waiving Xray (via .wrappedJSObject), the object
// we're passing from win1 to win2 is actually the waived object (which has
// a distinct identity in the compartment of win2). So this means that we're
// actually giving win2 Xray waivers to win1! This doesn't affect things as
// long as the security wrappers check documentDomainMakesSameOrigin directly
// for the puncture case rather than checking IsTransparent(), but it still
// gives rise to a situation that wouldn't really happen in practice.
function runContentContentTest(win1, win2, shouldSucceed, msg) {
var p = win1.wrappedJSObject.tryToClone(win2.wrappedJSObject.testObject,
shouldSucceed, msg);
if (!shouldSucceed)
return;
return new Promise(function(resolve) {
p.then(function(cloneResult) {
is(Cu.waiveXrays(cloneResult).toSource(), win2.wrappedJSObject.testObject.toSource(),
"Clone should create an identical object");
resolve();
});
});
}
function tryToClone(obj, shouldSucceed, message) {
var success = false;
var sink = window.frames[0];
try { sink.postMessage(obj, '*'); success = true; }
catch (e) { message = message + ' (threw: ' + e.message + ')'; }
is(success, shouldSucceed, message);
}
]]>
</script>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml">
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=667388"
target="_blank">Mozilla Bug 667388</a>
<iframe id="sink" />
<!-- The first two are same-origin, the third is not. -->
<iframe id="frame1" onload="onFrameLoaded(1);" src="http://test1.example.org/tests/dom/tests/mochitest/general/file_clonewrapper.html" />
<iframe id="frame2" onload="onFrameLoaded(2);" src="http://test1.example.org/tests/dom/tests/mochitest/general/file_clonewrapper.html" />
<iframe id="frame3" onload="onFrameLoaded(3);" src="http://test2.example.org/tests/dom/tests/mochitest/general/file_clonewrapper.html" />
</body>
</window>