|
1 <!DOCTYPE HTML> |
|
2 <html> |
|
3 <!-- |
|
4 https://bugzilla.mozilla.org/show_bug.cgi?id=682299 |
|
5 --> |
|
6 <head> |
|
7 <title>Test for Bug 682299</title> |
|
8 <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> |
|
9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> |
|
10 <script type="application/javascript" src="/tests/content/media/test/manifest.js"></script> |
|
11 </head> |
|
12 <body> |
|
13 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=682299">Mozilla Bug 682299</a> |
|
14 <p id="display"></p> |
|
15 <div id="content" style="display: none"> |
|
16 |
|
17 </div> |
|
18 <pre id="test"> |
|
19 <script type="application/javascript"> |
|
20 |
|
21 /** Test for Bug 682299 **/ |
|
22 |
|
23 function createCanvas(width, height) { |
|
24 var c = document.createElement("canvas"); |
|
25 c.width = width; |
|
26 c.height = height; |
|
27 return c; |
|
28 } |
|
29 |
|
30 function testCanvasDrawImage(v) { |
|
31 var c = createCanvas(v.width, v.height); |
|
32 var ctx = c.getContext("2d"); |
|
33 ctx.drawImage(v, 0, 0); |
|
34 |
|
35 try { |
|
36 var data = ctx.getImageData(0, 0, 1, 1); |
|
37 ok(true, "drawImage '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' worked"); |
|
38 } catch(error) { |
|
39 ok(!v.crossOrigin && error.name === "SecurityError", "drawImage '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' failed"); |
|
40 v.tainted = true; |
|
41 } |
|
42 } |
|
43 |
|
44 function testCanvasCreatePattern(v) { |
|
45 var c = createCanvas(v.width, v.height); |
|
46 var ctx = c.getContext("2d"); |
|
47 ctx.fillStyle = ctx.createPattern(v, ""); |
|
48 ctx.fillRect(0, 0, c.width, c.height); |
|
49 |
|
50 try { |
|
51 var data = ctx.getImageData(0, 0, 1, 1); |
|
52 ok(true, "createPattern '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' worked"); |
|
53 } catch(error) { |
|
54 ok(!v.crossOrigin && error.name === "SecurityError", "createPattern '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' failed"); |
|
55 v.tainted = true; |
|
56 } |
|
57 } |
|
58 |
|
59 function testWebGL(v) { |
|
60 var tex = gl.createTexture(); |
|
61 gl.bindTexture(gl.TEXTURE_2D, tex); |
|
62 |
|
63 try { |
|
64 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, v); |
|
65 ok(true, "createTexture from '" + v.src + "' with crossOrigin='" + v.crossOrigin + "' worked"); |
|
66 } catch (error) { |
|
67 ok(!v.crossOrigin && error.name === "SecurityError", "createTexture from '" + v.src + "' with crossOrigin='" + v.crossOrigin + "' failed"); |
|
68 v.tainted = true; |
|
69 } |
|
70 } |
|
71 |
|
72 function testTaintedCanvas(v) { |
|
73 var c = createCanvas(v.width, v.height); |
|
74 var ctx = c.getContext("2d"); |
|
75 ctx.drawImage(v, 0, 0); |
|
76 |
|
77 try { |
|
78 var data = ctx.getImageData(0, 0, 1, 1); |
|
79 ok(false, "changing the CORS mode should not allow reading data from remote videos"); |
|
80 } catch (error) { |
|
81 ok(error.name === "SecurityError", "changing the CORS mode, drawImage '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' failed"); |
|
82 } |
|
83 } |
|
84 |
|
85 function vidDataSuccess(e) { |
|
86 ok(!e.target.error, "Load '" + e.target.src + "' with crossOrigin='" + e.target.crossOrigin + "'"); |
|
87 |
|
88 testCanvasDrawImage(e.target); |
|
89 testCanvasCreatePattern(e.target); |
|
90 if (gl) { |
|
91 testWebGL(e.target); |
|
92 } |
|
93 // If we change the CORS mode after loading the file without CORS it should still throw a security error |
|
94 if (e.target.tainted) { |
|
95 e.target.crossOrigin = "anonymous"; |
|
96 testTaintedCanvas(e.target); |
|
97 } |
|
98 |
|
99 doneTest(e); |
|
100 } |
|
101 |
|
102 function vidLoadFailure(e) { |
|
103 ok(false, "Load '" + e.target.src + "' with crossOrigin='" + e.target.crossOrigin + "'"); |
|
104 doneTest(e); |
|
105 } |
|
106 |
|
107 function vidErrorSuccess(e) { |
|
108 ok(e.target.error.code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED, |
|
109 "Load '" + e.target.src + "' with crossOrigin='" + e.target.crossOrigin + "'"); |
|
110 doneTest(e); |
|
111 } |
|
112 |
|
113 function startTest(test, token) { |
|
114 var v = document.createElement('video'); |
|
115 if (test.cors === "just-crossOrigin-without-value") { |
|
116 var div = document.createElement('div'); |
|
117 div.innerHTML="<video crossOrigin>"; |
|
118 v = div.children[0]; |
|
119 } else if (test.cors !== "missing-value-default") { |
|
120 v.crossOrigin = test.cors; |
|
121 } |
|
122 v.token = token; |
|
123 manager.started(token); |
|
124 v.autoplay = true; |
|
125 v.preload = "auto"; |
|
126 v.style.display = "none"; |
|
127 if (test.nameIntent === test.corsIntent || test.corsIntent === "none" || |
|
128 (test.nameIntent === "use-credentials" && test.corsIntent === "anonymous")) { |
|
129 v.addEventListener("loadeddata", vidDataSuccess, false); |
|
130 v.addEventListener("error", vidLoadFailure, false); |
|
131 } else { |
|
132 v.addEventListener("loadeddata", vidLoadFailure, false); |
|
133 v.addEventListener("error", vidErrorSuccess, false); |
|
134 } |
|
135 v.src = test.name; |
|
136 document.body.appendChild(v); |
|
137 } |
|
138 |
|
139 function doneTest(e) { |
|
140 var v = e.target; |
|
141 v.parentNode.removeChild(v); |
|
142 manager.finished(v.token); |
|
143 } |
|
144 |
|
145 var videoFile = getPlayableVideo(gSmallTests); |
|
146 if (!videoFile) { |
|
147 SimpleTest.finish(); |
|
148 } |
|
149 videoFile = "?name=tests/content/media/test/" + videoFile.name + "&type=" + videoFile.type; |
|
150 |
|
151 var gl; |
|
152 try { |
|
153 gl = createCanvas(16, 16).getContext("experimental-webgl"); |
|
154 } catch (ex) { |
|
155 // Mac OS X 10.5 doesn't support WebGL, so we won't run the WebGL tests |
|
156 } |
|
157 |
|
158 var manager = new MediaTestManager; |
|
159 var corsTests = []; |
|
160 |
|
161 const host = "http://example.com/tests/content/canvas/test/crossorigin/video.sjs"; |
|
162 const serverAttrValues = [ |
|
163 [ "&cors=none", "none" ], |
|
164 [ "&cors=anonymous", "anonymous" ], |
|
165 [ "&cors=use-credentials", "use-credentials" ] |
|
166 ]; |
|
167 const clientAttrValues = [ |
|
168 [ "missing-value-default", "none" ], |
|
169 [ "", "anonymous" ], |
|
170 [ "just-crossOrigin-without-value", "anonymous" ], |
|
171 [ "anonymous", "anonymous" ], |
|
172 [ "use-credentials", "use-credentials" ], |
|
173 [ "foobar", "anonymous" ] |
|
174 ]; |
|
175 |
|
176 // Build the video file test array |
|
177 for (var i = 0; i < serverAttrValues.length; i++) { |
|
178 for (var n = 0; n < clientAttrValues.length; n++) { |
|
179 corsTests.push({ |
|
180 name: host + videoFile + serverAttrValues[i][0], |
|
181 nameIntent: serverAttrValues[i][1], |
|
182 cors: clientAttrValues[n][0], |
|
183 corsIntent: clientAttrValues[n][1] |
|
184 }); |
|
185 } |
|
186 } |
|
187 |
|
188 manager.runTests(corsTests, startTest); |
|
189 |
|
190 </script> |
|
191 </pre> |
|
192 </body> |
|
193 </html> |