1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/tests/mochitest/chrome/test_clonewrapper.xul Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,126 @@ 1.4 +<?xml version="1.0"?> 1.5 +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> 1.6 +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> 1.7 +<!-- 1.8 +https://bugzilla.mozilla.org/show_bug.cgi?id=667388 1.9 +--> 1.10 +<window title="Mozilla Bug 667388" 1.11 + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> 1.12 + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> 1.13 + 1.14 + <!-- test code goes here --> 1.15 + <script type="application/javascript"> 1.16 + <![CDATA[ 1.17 + 1.18 + // Setup. 1.19 + SimpleTest.waitForExplicitFinish(); 1.20 + window.testObject = { myNumber: 42, 1.21 + myDomain: window.location.domain }; 1.22 + 1.23 + 1.24 + // Wait for both frames to load before proceeding. 1.25 + var framesLoaded = [null, false, false, false]; 1.26 + function onFrameLoaded(id) { 1.27 + 1.28 + // Mark this frame as loaded. 1.29 + framesLoaded[id] = true; 1.30 + 1.31 + // Allow it to call |is|. 1.32 + window.frames[id].wrappedJSObject.is = is; 1.33 + 1.34 + // If all the frames are loaded, start the test. 1.35 + if (framesLoaded[1] && framesLoaded[2] && framesLoaded[3]) 1.36 + startTest(); 1.37 + } 1.38 + 1.39 + function startTest() { 1.40 + 1.41 + // Test interaction between chrome and content. 1.42 + runChromeContentTest(window.frames[1]); 1.43 + 1.44 + // Try same origin. 1.45 + runContentContentTest(window.frames[1], window.frames[2], 1.46 + true, "Should be able to clone same-origin"); 1.47 + 1.48 + // Try cross-origin. 1.49 + runContentContentTest(window.frames[2], window.frames[3], 1.50 + false, "Should not be able to clone cross-origin"); 1.51 + 1.52 + // Colaborate with document.domain, then try again. 1.53 + frames[2].document.domain = 'example.org'; 1.54 + frames[3].document.domain = 'example.org'; 1.55 + runContentContentTest(window.frames[2], window.frames[3], 1.56 + true, "Should be able to clone cross-origin with document.domain") 1.57 + 1.58 + SimpleTest.finish(); 1.59 + } 1.60 + 1.61 + // Tests cloning between chrome and content. 1.62 + function runChromeContentTest(contentWin) { 1.63 + 1.64 + // We should be able to clone a content object. 1.65 + tryToClone(contentWin.wrappedJSObject.testObject, 1.66 + true, 1.67 + "Chrome should be able to clone content object"); 1.68 + 1.69 + // Content should not be able to clone a chrome object. 1.70 + // 1.71 + // Note that because we're using |wrappedJSObject| here, the subject 1.72 + // principal is clamed to the principal of the iframe, which is what we want. 1.73 + contentWin.wrappedJSObject.tryToClone(window.testObject, false, 1.74 + "Content should not be able to clone chrome object"); 1.75 + } 1.76 + 1.77 + // Test cloning between content and content. 1.78 + // 1.79 + // Note - the way we do this is kind of sketchy. Because we're grabbing the 1.80 + // test object from win1 by waiving Xray (via .wrappedJSObject), the object 1.81 + // we're passing from win1 to win2 is actually the waived object (which has 1.82 + // a distinct identity in the compartment of win2). So this means that we're 1.83 + // actually giving win2 Xray waivers to win1! This doesn't affect things as 1.84 + // long as the security wrappers check documentDomainMakesSameOrigin directly 1.85 + // for the puncture case rather than checking IsTransparent(), but it still 1.86 + // gives rise to a situation that wouldn't really happen in practice. 1.87 + // 1.88 + // A more serious issues is that we don't/can't test the Xray wrapper path, 1.89 + // because the only native objects that we successfully send through 1.90 + // structured clone don't force a parent in PreCreate, and so we _can't_ 1.91 + // have security wrappers around them (we get a new XPCWN in each 1.92 + // compartment). Since the case can't happen, we can't write tests for it. 1.93 + // But when it can happen (ie, we fix PreCreate for File, FileList, Blob, etc), 1.94 + // we want tests right away, because this stuff is very security-sensitive. 1.95 + // So we set this test up to fail when things are fixed, so that the someone 1.96 + // will notice and properly augment this test to cover native objects. 1.97 + function runContentContentTest(win1, win2, shouldSucceed, msg) { 1.98 + win1.wrappedJSObject.tryToClone(win2.wrappedJSObject.testObject, 1.99 + shouldSucceed, msg); 1.100 + 1.101 + var fixMsg = "If this fails, you fixed PreCreate. That's a good thing, "; 1.102 + fixMsg += "but now we need some test coverage. See the above comment."; 1.103 + win1.wrappedJSObject.tryToClone(win2.wrappedJSObject.blob, true, fixMsg); 1.104 + win1.wrappedJSObject.tryToClone(win2.wrappedJSObject.filelist, true, fixMsg); 1.105 + } 1.106 + 1.107 + function tryToClone(obj, shouldSucceed, message) { 1.108 + var success = false; 1.109 + var sink = window.frames[0]; 1.110 + try { sink.postMessage(obj, '*'); success = true; } 1.111 + catch (e) { message = message + ' (threw: ' + e.message + ')'; } 1.112 + is(success, shouldSucceed, message); 1.113 + } 1.114 + 1.115 + ]]> 1.116 + </script> 1.117 + 1.118 + <!-- test results are displayed in the html:body --> 1.119 + <body xmlns="http://www.w3.org/1999/xhtml"> 1.120 + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=667388" 1.121 + target="_blank">Mozilla Bug 667388</a> 1.122 + <iframe id="sink" /> 1.123 + <!-- The first two are same-origin, the third is not. --> 1.124 + <iframe id="frame1" onload="onFrameLoaded(1);" src="http://test1.example.org/tests/dom/tests/mochitest/general/file_clonewrapper.html" /> 1.125 + <iframe id="frame2" onload="onFrameLoaded(2);" src="http://test1.example.org/tests/dom/tests/mochitest/general/file_clonewrapper.html" /> 1.126 + <iframe id="frame3" onload="onFrameLoaded(3);" src="http://test2.example.org/tests/dom/tests/mochitest/general/file_clonewrapper.html" /> 1.127 + </body> 1.128 + 1.129 +</window>