Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | <?xml version="1.0"?> |
michael@0 | 2 | <?xml-stylesheet type="text/css" href="chrome://global/skin"?> |
michael@0 | 3 | <?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> |
michael@0 | 4 | <!-- |
michael@0 | 5 | https://bugzilla.mozilla.org/show_bug.cgi?id=667388 |
michael@0 | 6 | --> |
michael@0 | 7 | <window title="Mozilla Bug 667388" |
michael@0 | 8 | xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> |
michael@0 | 9 | <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> |
michael@0 | 10 | |
michael@0 | 11 | <!-- test code goes here --> |
michael@0 | 12 | <script type="application/javascript"> |
michael@0 | 13 | <![CDATA[ |
michael@0 | 14 | |
michael@0 | 15 | // Setup. |
michael@0 | 16 | SimpleTest.waitForExplicitFinish(); |
michael@0 | 17 | window.testObject = { myNumber: 42, |
michael@0 | 18 | myDomain: window.location.domain }; |
michael@0 | 19 | |
michael@0 | 20 | |
michael@0 | 21 | // Wait for both frames to load before proceeding. |
michael@0 | 22 | var framesLoaded = [null, false, false, false]; |
michael@0 | 23 | function onFrameLoaded(id) { |
michael@0 | 24 | |
michael@0 | 25 | // Mark this frame as loaded. |
michael@0 | 26 | framesLoaded[id] = true; |
michael@0 | 27 | |
michael@0 | 28 | // Allow it to call |is|. |
michael@0 | 29 | window.frames[id].wrappedJSObject.is = is; |
michael@0 | 30 | |
michael@0 | 31 | // If all the frames are loaded, start the test. |
michael@0 | 32 | if (framesLoaded[1] && framesLoaded[2] && framesLoaded[3]) |
michael@0 | 33 | startTest(); |
michael@0 | 34 | } |
michael@0 | 35 | |
michael@0 | 36 | function startTest() { |
michael@0 | 37 | |
michael@0 | 38 | // Test interaction between chrome and content. |
michael@0 | 39 | runChromeContentTest(window.frames[1]); |
michael@0 | 40 | |
michael@0 | 41 | // Try same origin. |
michael@0 | 42 | runContentContentTest(window.frames[1], window.frames[2], |
michael@0 | 43 | true, "Should be able to clone same-origin"); |
michael@0 | 44 | |
michael@0 | 45 | // Try cross-origin. |
michael@0 | 46 | runContentContentTest(window.frames[2], window.frames[3], |
michael@0 | 47 | false, "Should not be able to clone cross-origin"); |
michael@0 | 48 | |
michael@0 | 49 | // Colaborate with document.domain, then try again. |
michael@0 | 50 | frames[2].document.domain = 'example.org'; |
michael@0 | 51 | frames[3].document.domain = 'example.org'; |
michael@0 | 52 | runContentContentTest(window.frames[2], window.frames[3], |
michael@0 | 53 | true, "Should be able to clone cross-origin with document.domain") |
michael@0 | 54 | |
michael@0 | 55 | SimpleTest.finish(); |
michael@0 | 56 | } |
michael@0 | 57 | |
michael@0 | 58 | // Tests cloning between chrome and content. |
michael@0 | 59 | function runChromeContentTest(contentWin) { |
michael@0 | 60 | |
michael@0 | 61 | // We should be able to clone a content object. |
michael@0 | 62 | tryToClone(contentWin.wrappedJSObject.testObject, |
michael@0 | 63 | true, |
michael@0 | 64 | "Chrome should be able to clone content object"); |
michael@0 | 65 | |
michael@0 | 66 | // Content should not be able to clone a chrome object. |
michael@0 | 67 | // |
michael@0 | 68 | // Note that because we're using |wrappedJSObject| here, the subject |
michael@0 | 69 | // principal is clamed to the principal of the iframe, which is what we want. |
michael@0 | 70 | contentWin.wrappedJSObject.tryToClone(window.testObject, false, |
michael@0 | 71 | "Content should not be able to clone chrome object"); |
michael@0 | 72 | } |
michael@0 | 73 | |
michael@0 | 74 | // Test cloning between content and content. |
michael@0 | 75 | // |
michael@0 | 76 | // Note - the way we do this is kind of sketchy. Because we're grabbing the |
michael@0 | 77 | // test object from win1 by waiving Xray (via .wrappedJSObject), the object |
michael@0 | 78 | // we're passing from win1 to win2 is actually the waived object (which has |
michael@0 | 79 | // a distinct identity in the compartment of win2). So this means that we're |
michael@0 | 80 | // actually giving win2 Xray waivers to win1! This doesn't affect things as |
michael@0 | 81 | // long as the security wrappers check documentDomainMakesSameOrigin directly |
michael@0 | 82 | // for the puncture case rather than checking IsTransparent(), but it still |
michael@0 | 83 | // gives rise to a situation that wouldn't really happen in practice. |
michael@0 | 84 | // |
michael@0 | 85 | // A more serious issues is that we don't/can't test the Xray wrapper path, |
michael@0 | 86 | // because the only native objects that we successfully send through |
michael@0 | 87 | // structured clone don't force a parent in PreCreate, and so we _can't_ |
michael@0 | 88 | // have security wrappers around them (we get a new XPCWN in each |
michael@0 | 89 | // compartment). Since the case can't happen, we can't write tests for it. |
michael@0 | 90 | // But when it can happen (ie, we fix PreCreate for File, FileList, Blob, etc), |
michael@0 | 91 | // we want tests right away, because this stuff is very security-sensitive. |
michael@0 | 92 | // So we set this test up to fail when things are fixed, so that the someone |
michael@0 | 93 | // will notice and properly augment this test to cover native objects. |
michael@0 | 94 | function runContentContentTest(win1, win2, shouldSucceed, msg) { |
michael@0 | 95 | win1.wrappedJSObject.tryToClone(win2.wrappedJSObject.testObject, |
michael@0 | 96 | shouldSucceed, msg); |
michael@0 | 97 | |
michael@0 | 98 | var fixMsg = "If this fails, you fixed PreCreate. That's a good thing, "; |
michael@0 | 99 | fixMsg += "but now we need some test coverage. See the above comment."; |
michael@0 | 100 | win1.wrappedJSObject.tryToClone(win2.wrappedJSObject.blob, true, fixMsg); |
michael@0 | 101 | win1.wrappedJSObject.tryToClone(win2.wrappedJSObject.filelist, true, fixMsg); |
michael@0 | 102 | } |
michael@0 | 103 | |
michael@0 | 104 | function tryToClone(obj, shouldSucceed, message) { |
michael@0 | 105 | var success = false; |
michael@0 | 106 | var sink = window.frames[0]; |
michael@0 | 107 | try { sink.postMessage(obj, '*'); success = true; } |
michael@0 | 108 | catch (e) { message = message + ' (threw: ' + e.message + ')'; } |
michael@0 | 109 | is(success, shouldSucceed, message); |
michael@0 | 110 | } |
michael@0 | 111 | |
michael@0 | 112 | ]]> |
michael@0 | 113 | </script> |
michael@0 | 114 | |
michael@0 | 115 | <!-- test results are displayed in the html:body --> |
michael@0 | 116 | <body xmlns="http://www.w3.org/1999/xhtml"> |
michael@0 | 117 | <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=667388" |
michael@0 | 118 | target="_blank">Mozilla Bug 667388</a> |
michael@0 | 119 | <iframe id="sink" /> |
michael@0 | 120 | <!-- The first two are same-origin, the third is not. --> |
michael@0 | 121 | <iframe id="frame1" onload="onFrameLoaded(1);" src="http://test1.example.org/tests/dom/tests/mochitest/general/file_clonewrapper.html" /> |
michael@0 | 122 | <iframe id="frame2" onload="onFrameLoaded(2);" src="http://test1.example.org/tests/dom/tests/mochitest/general/file_clonewrapper.html" /> |
michael@0 | 123 | <iframe id="frame3" onload="onFrameLoaded(3);" src="http://test2.example.org/tests/dom/tests/mochitest/general/file_clonewrapper.html" /> |
michael@0 | 124 | </body> |
michael@0 | 125 | |
michael@0 | 126 | </window> |