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