| <!doctype html> |
| <html> |
| <body> |
| <pre id="console"></pre> |
| <script> |
| if (window.testRunner) { |
| testRunner.dumpAsText(); |
| testRunner.waitUntilDone(); |
| } |
| |
| log = function(msg) |
| { |
| document.getElementById('console').appendChild(document.createTextNode(msg + "\n")); |
| } |
| |
| testTexImage2D = function(gl, source, description) |
| { |
| description = "Calling texImage2D() with an untainted " + description; |
| try { |
| gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source); |
| log("PASS: " + description + " was allowed"); |
| } catch (e) { |
| log("FAIL: " + description + " was not allowed: Threw error: " + e + "."); |
| } |
| } |
| |
| testReadPixels = function(gl, description) |
| { |
| description = "Calling readPixels() from a canvas tainted by a " + description; |
| try { |
| var pixels = new Uint8Array(4); |
| gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels); |
| log("PASS: " + description + " was allowed."); |
| } catch (e) { |
| log("FAIL: " + description + " was not allowed - Threw error: " + e + "."); |
| } |
| } |
| |
| testToDataURL = function(canvas, description) |
| { |
| description = "Calling toDataURL() on a canvas CORS-untainted by a " + description; |
| try { |
| var dataURL = canvas.toDataURL(); |
| log("PASS: " + description + " was allowed."); |
| } catch (e) { |
| log("FAIL: " + description + " was not allowed - Threw error: " + e + "."); |
| } |
| } |
| |
| test = function(canvas, description) |
| { |
| testReadPixels(canvas.getContext("webgl"), description); |
| testToDataURL(canvas, description); |
| } |
| |
| testResource = function (resource, resourceType, continuation) |
| { |
| log(""); |
| log("Testing " + resourceType + "..."); |
| |
| var canvas = document.createElement("canvas"); |
| canvas.width = 100; |
| canvas.height = 100; |
| var gl = canvas.getContext("webgl"); |
| |
| // Control tests |
| log("Untainted canvas:"); |
| try { |
| var pixels = new Uint8Array(4); |
| gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels); |
| log("PASS: Calling readPixels() from an untainted canvas was allowed."); |
| } catch (e) { |
| log("FAIL: Calling readPixels() from an untainted canvas was not allowed: Threw error: " + e + "."); |
| } |
| try { |
| var dataURL = canvas.toDataURL(); |
| log("PASS: Calling toDataURL() on an untainted canvas was allowed."); |
| } catch (e) { |
| log("FAIL: Calling toDataURL() on an untainted canvas was not allowed: Threw error: " + e + "."); |
| } |
| |
| log("\n"); |
| log("Tainted canvas:"); |
| // Test reading from a canvas after uploading a remote resource as a texture |
| var texture = gl.createTexture(); |
| gl.bindTexture(gl.TEXTURE_2D, texture); |
| testTexImage2D(gl, resource, resourceType); |
| |
| test(canvas, "remote " + resourceType); |
| |
| // Now test reading from a canvas after uploading a tainted canvas onto it |
| var dirtyCanvas = document.createElement("canvas"); |
| dirtyCanvas.width = 100; |
| dirtyCanvas.height = 100; |
| var dirtyContext = dirtyCanvas.getContext("2d"); |
| dirtyContext.drawImage(resource, 0, 0, 100, 100); |
| testTexImage2D(gl, dirtyCanvas, "canvas"); |
| |
| test(canvas, "CORS-untained canvas"); |
| |
| continuation(); |
| } |
| |
| testImage = function () |
| { |
| var image = new Image(); |
| image.onload = testResource.bind(null, image, "image", testVideo); |
| image.crossOrigin = "anonymous"; |
| image.src = "http://localhost:8000/security/resources/abe-allow-star.php"; |
| } |
| |
| testVideo = function () |
| { |
| var video = document.createElement('video'); |
| video.oncanplay = testResource.bind(null, video, "video", finishUp); |
| video.crossOrigin = "anonymous"; |
| var name = "../../media/resources/test.ogv"; |
| var type = "video/ogg"; |
| video.src = "http://localhost:8000/security/resources/video-cross-origin-allow.php?name=" + name + "&type=" + type; |
| } |
| |
| finishUp = function () |
| { |
| log("DONE"); |
| if (window.testRunner) |
| testRunner.notifyDone(); |
| } |
| |
| testImage(); |
| </script> |
| </body> |
| </html> |