test_video_crossorigin.html (6778B)
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 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/dom/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 SimpleTest.requestFlakyTimeout("untriaged"); 23 24 function createCanvas(width, height) { 25 var c = document.createElement("canvas"); 26 c.width = width; 27 c.height = height; 28 return c; 29 } 30 31 function checkGetImageData(ctx, v) { 32 try { 33 var data = ctx.getImageData(0, 0, 1, 1); 34 ok(true, "drawImage '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' worked"); 35 } catch(error) { 36 ok(!v.crossOrigin && error.name === "SecurityError", "drawImage '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' failed"); 37 v.tainted = true; 38 } 39 } 40 41 function checkGetImageDataTainted(ctx, v) { 42 try { 43 var data = ctx.getImageData(0, 0, 1, 1); 44 ok(false, "changing the CORS mode should not allow reading data from remote videos"); 45 } catch (error) { 46 ok(error.name === "SecurityError", "changing the CORS mode, drawImage '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' failed"); 47 } 48 } 49 50 function checkCaptureStream(c, v) { 51 try { 52 var stream = c.captureStream(0); 53 ok(true, "drawImage '" + v.src + "' then captureStream with crossOrigin='" + v.crossOrigin + "' worked"); 54 } catch(error) { 55 ok(!v.crossOrigin && error.name === "SecurityError", "drawImage '" + v.src + "' then captureStream with crossOrigin='" + v.crossOrigin + "' failed"); 56 v.tainted = true; 57 } 58 } 59 60 function checkCaptureStreamTainted(c, v) { 61 try { 62 var stream = c.captureStream(0); 63 ok(false, "changing the CORS mode should not allow capturing a stream from remote videos"); 64 } catch (error) { 65 ok(error.name === "SecurityError", "changing the CORS mode, drawImage '" + v.src + "' then captureStream with crossOrigin='" + v.crossOrigin + "' failed"); 66 } 67 } 68 69 function testCanvasDrawImage(v) { 70 var c = createCanvas(v.width, v.height); 71 var ctx = c.getContext("2d"); 72 ctx.drawImage(v, 0, 0); 73 74 checkGetImageData(ctx, v); 75 checkCaptureStream(c, v); 76 } 77 78 function testCanvasCreatePattern(v) { 79 var c = createCanvas(v.width, v.height); 80 var ctx = c.getContext("2d"); 81 ctx.fillStyle = ctx.createPattern(v, ""); 82 ctx.fillRect(0, 0, c.width, c.height); 83 84 checkGetImageData(ctx, v); 85 checkCaptureStream(c, v); 86 } 87 88 function testWebGL(gl, v) { 89 var tex = gl.createTexture(); 90 gl.bindTexture(gl.TEXTURE_2D, tex); 91 92 try { 93 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, v); 94 ok(true, "createTexture from '" + v.src + "' with crossOrigin='" + v.crossOrigin + "' worked"); 95 } catch (error) { 96 ok(!v.crossOrigin && error.name === "SecurityError", "createTexture from '" + v.src + "' with crossOrigin='" + v.crossOrigin + "' failed"); 97 v.tainted = true; 98 } 99 } 100 101 function testTaintedCanvas(v) { 102 var c = createCanvas(v.width, v.height); 103 var ctx = c.getContext("2d"); 104 ctx.drawImage(v, 0, 0); 105 106 checkGetImageDataTainted(ctx, v); 107 checkCaptureStreamTainted(c, v); 108 } 109 110 function vidDataSuccess(e) { 111 ok(!e.target.error, "Load '" + e.target.src + "' with crossOrigin='" + e.target.crossOrigin + "'"); 112 113 testCanvasDrawImage(e.target); 114 testCanvasCreatePattern(e.target); 115 if (document.gl) { 116 testWebGL(document.gl, e.target); 117 } 118 // If we change the CORS mode after loading the file without CORS it should still throw a security error 119 if (e.target.tainted) { 120 e.target.crossOrigin = "anonymous"; 121 testTaintedCanvas(e.target); 122 } 123 124 doneTest(e); 125 } 126 127 function vidLoadFailure(e) { 128 ok(false, "Load '" + e.target.src + "' with crossOrigin='" + e.target.crossOrigin + "'"); 129 doneTest(e); 130 } 131 132 function vidErrorSuccess(e) { 133 ok(e.target.error.code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED, 134 "Load '" + e.target.src + "' with crossOrigin='" + e.target.crossOrigin + "'"); 135 doneTest(e); 136 } 137 138 function startTest(test, token) { 139 var v = document.createElement('video'); 140 if (test.cors === "just-crossOrigin-without-value") { 141 var div = document.createElement('div'); 142 div.innerHTML="<video crossOrigin>"; 143 v = div.children[0]; 144 } else if (test.cors !== "missing-value-default") { 145 v.crossOrigin = test.cors; 146 } 147 v.token = token; 148 document.manager.started(token); 149 v.autoplay = true; 150 v.preload = "auto"; 151 v.style.display = "none"; 152 if (test.nameIntent === test.corsIntent || test.corsIntent === "none" || 153 (test.nameIntent === "use-credentials" && test.corsIntent === "anonymous")) { 154 v.addEventListener("loadeddata", vidDataSuccess); 155 v.addEventListener("error", vidLoadFailure); 156 } else { 157 v.addEventListener("loadeddata", vidLoadFailure); 158 v.addEventListener("error", vidErrorSuccess); 159 } 160 v.src = test.name; 161 document.body.appendChild(v); 162 } 163 164 function doneTest(e) { 165 var v = e.target; 166 v.remove(); 167 document.manager.finished(v.token); 168 } 169 170 function beginTest() { 171 var videoFile = getPlayableVideo(gSmallTests); 172 if (!videoFile) { 173 SimpleTest.finish(); 174 } 175 videoFile = "?name=tests/dom/media/test/" + videoFile.name + "&type=" + videoFile.type; 176 177 document.manager = new MediaTestManager; 178 var corsTests = []; 179 180 const host = "http://example.com/tests/dom/canvas/test/crossorigin/video.sjs"; 181 const serverAttrValues = [ 182 [ "&cors=none", "none" ], 183 [ "&cors=anonymous", "anonymous" ], 184 [ "&cors=use-credentials", "use-credentials" ] 185 ]; 186 const clientAttrValues = [ 187 [ "missing-value-default", "none" ], 188 [ "", "anonymous" ], 189 [ "just-crossOrigin-without-value", "anonymous" ], 190 [ "anonymous", "anonymous" ], 191 [ "use-credentials", "use-credentials" ], 192 [ "foobar", "anonymous" ] 193 ]; 194 195 // Build the video file test array 196 for (var i = 0; i < serverAttrValues.length; i++) { 197 for (var n = 0; n < clientAttrValues.length; n++) { 198 corsTests.push({ 199 name: host + videoFile + serverAttrValues[i][0], 200 nameIntent: serverAttrValues[i][1], 201 cors: clientAttrValues[n][0], 202 corsIntent: clientAttrValues[n][1] 203 }); 204 } 205 } 206 try { 207 document.gl = createCanvas(16, 16).getContext("experimental-webgl"); 208 } catch (ex) { 209 // Mac OS X 10.5 doesn't support WebGL, so we won't run the WebGL tests 210 } 211 document.manager.runTests(corsTests, startTest); 212 } 213 214 SimpleTest.waitForExplicitFinish(); 215 beginTest(); 216 </script> 217 </pre> 218 </body> 219 </html>