summaryrefslogtreecommitdiffstats
path: root/LayoutTests/http
diff options
context:
space:
mode:
Diffstat (limited to 'LayoutTests/http')
-rw-r--r--LayoutTests/http/tests/canvas/webgl/origin-clean-conformance-expected.txt29
-rw-r--r--LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html218
-rw-r--r--LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-expected.txt15
-rw-r--r--LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials-expected.txt15
-rw-r--r--LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials.html108
-rw-r--r--LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed.html108
-rw-r--r--LayoutTests/http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin-expected.txt15
-rw-r--r--LayoutTests/http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin.html108
-rw-r--r--LayoutTests/http/tests/security/resources/abe-allow-credentials.php12
-rw-r--r--LayoutTests/http/tests/security/resources/abe-allow-star.php11
-rw-r--r--LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt13
-rw-r--r--LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt13
-rw-r--r--LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html101
-rw-r--r--LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed.html101
-rw-r--r--LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt13
-rw-r--r--LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html103
16 files changed, 983 insertions, 0 deletions
diff --git a/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance-expected.txt b/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance-expected.txt
new file mode 100644
index 0000000..ca9217c
--- /dev/null
+++ b/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance-expected.txt
@@ -0,0 +1,29 @@
+This test ensures WebGL implementations follow proper same-origin restrictions.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS Playable video format found
+PASS img was loaded
+
+check that an attempt to upload an image from another origin throws an exception.
+PASS texImage2D with cross-origin image should throw exception.
+PASS texSubImage2D with cross-origin image should throw exception.
+check that readPixels and toDataURL continue to work against this canvas.
+PASS readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.
+PASS should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.
+check that an attempt to upload a tainted canvas throws an exception.
+PASS should throw exception by toDataURL for NON origin clean canvas.
+PASS texImage2D with NON origin clean canvas should throw exception.
+PASS texSubImage2D with NON origin clean canvas should throw exception.
+check that readPixels and toDataURL continue to work against this canvas.
+PASS readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.
+PASS should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.
+check that an attempt to upload a video from another origin throws an exception.
+PASS texImage2D with cross-origin video should throw exception.
+PASS texSubImage2D with cross-origin video should throw exception.
+check that readPixels and toDataURL continue to work against this canvas.
+PASS readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.
+PASS should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html b/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html
new file mode 100644
index 0000000..e983616
--- /dev/null
+++ b/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html
@@ -0,0 +1,218 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Origin Restrictions Conformance Tests</title>
+<script>
+function create3DContext(canvas, attributes)
+{
+ if (!canvas)
+ canvas = document.createElement("canvas");
+ var context = null;
+ try {
+ context = canvas.getContext("experimental-webgl", attributes);
+ } catch(e) {}
+ if (!context) {
+ try {
+ context = canvas.getContext("webkit-3d", attributes);
+ } catch(e) {}
+ }
+ if (!context) {
+ try {
+ context = canvas.getContext("moz-webgl", attributes);
+ } catch(e) {}
+ }
+ if (!context) {
+ throw "Unable to fetch WebGL rendering context for Canvas";
+ }
+ return context;
+}
+
+function description(msg)
+{
+ // For MSIE 6 compatibility
+ var span = document.createElement("span");
+ span.innerHTML = '<p>' + msg + '</p><p>On success, you will see a series of "<span class="pass">PASS</span>" messages, followed by "<span class="pass">TEST COMPLETE</span>".</p>';
+ var description = document.getElementById("description");
+ if (description.firstChild)
+ description.replaceChild(span, description.firstChild);
+ else
+ description.appendChild(span);
+}
+
+function debug(msg)
+{
+ var span = document.createElement("span");
+ document.getElementById("console").appendChild(span); // insert it first so XHTML knows the namespace
+ span.innerHTML = msg + '<br />';
+}
+
+function escapeHTML(text)
+{
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/\0/g, "\\0");
+}
+
+function testPassed(msg)
+{
+ debug('<span><span class="pass">PASS</span> ' + escapeHTML(msg) + '</span>');
+}
+
+function testFailed(msg)
+{
+ debug('<span><span class="fail">FAIL</span> ' + escapeHTML(msg) + '</span>');
+}
+
+function assertMsg(assertion, msg) {
+ if (assertion) {
+ testPassed(msg);
+ } else {
+ testFailed(msg);
+ }
+}
+
+// Checks if function throws an exception.
+function causedException(func) {
+ var hadException = false;
+ try {
+ func();
+ } catch(e) {
+ hadException = true;
+ }
+ return hadException;
+}
+
+var testVideo = false;
+
+function init() {
+ var video = document.getElementById("video");
+
+ var base = "http://localhost:8000/resources/";
+ var videos = [
+ ["video/mp4", base + "test.mp4"],
+ ["video/ogg", base + "test.ogv"],
+ ];
+ var videoFile = null;
+ for (var i = 0; i < videos.length; ++i) {
+ if (video.canPlayType(videos[i][0])) {
+ videoFile = videos[i][1];
+ break;
+ }
+ }
+ assertMsg(videoFile, "Playable video format found");
+
+ if (videoFile) {
+ if (window.layoutTestController) {
+ layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+ }
+ video.src = videoFile;
+ video.addEventListener("playing", runTests);
+ video.play();
+ testVideo = true;
+ } else {
+ // Still run the other tests, even if the video failed.
+ runTests();
+ }
+}
+
+function runTests() {
+ description("This test ensures WebGL implementations follow proper same-origin restrictions.");
+ var img = document.getElementById("img");
+ assertMsg(img.width > 0 && img.height > 0, "img was loaded");
+
+ function makeTexImage2D(gl, src) {
+ return function() {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);
+ };
+ }
+
+ function makeTexSubImage2D(gl, src) {
+ return function() {
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src);
+ };
+ }
+
+ function makeReadPixels(gl) {
+ return function() {
+ var buf = new Uint8Array(4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ };
+ }
+
+ function makeToDataURL(canvas) {
+ return function() {
+ var data = canvas.toDataURL();
+ }
+ }
+
+ var canvas1 = document.getElementById("canvas1");
+ var gl = create3DContext(canvas1);
+
+ debug("");
+ debug("check that an attempt to upload an image from another origin throws an exception.");
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 256, 256, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ assertMsg(causedException(makeTexImage2D(gl, img)),
+ "texImage2D with cross-origin image should throw exception.");
+ assertMsg(causedException(makeTexSubImage2D(gl, img)),
+ "texSubImage2D with cross-origin image should throw exception.");
+
+ debug("check that readPixels and toDataURL continue to work against this canvas.");
+ assertMsg(!causedException(makeReadPixels(gl)),
+ "readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.");
+ assertMsg(!causedException(makeToDataURL(canvas1)),
+ "should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.");
+
+ debug("check that an attempt to upload a tainted canvas throws an exception.");
+ var canvas2 = document.getElementById("canvas2");
+ var ctx2d = canvas2.getContext("2d");
+ ctx2d.drawImage(img, 0, 0);
+ assertMsg(causedException(makeToDataURL(canvas2)),
+ "should throw exception by toDataURL for NON origin clean canvas.");
+ assertMsg(causedException(makeTexImage2D(gl, canvas2)),
+ "texImage2D with NON origin clean canvas should throw exception.");
+ assertMsg(causedException(makeTexSubImage2D(gl, canvas2)),
+ "texSubImage2D with NON origin clean canvas should throw exception.");
+
+ debug("check that readPixels and toDataURL continue to work against this canvas.");
+ assertMsg(!causedException(makeReadPixels(gl)),
+ "readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.");
+ assertMsg(!causedException(makeToDataURL(canvas1)),
+ "should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.");
+
+ if (testVideo) {
+ debug("check that an attempt to upload a video from another origin throws an exception.");
+ var video = document.getElementById("video");
+ assertMsg(causedException(makeTexImage2D(gl, video)),
+ "texImage2D with cross-origin video should throw exception.");
+ assertMsg(causedException(makeTexSubImage2D(gl, video)),
+ "texSubImage2D with cross-origin video should throw exception.");
+
+ debug("check that readPixels and toDataURL continue to work against this canvas.");
+ assertMsg(!causedException(makeReadPixels(gl)),
+ "readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.");
+ assertMsg(!causedException(makeToDataURL(canvas1)),
+ "should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.");
+ }
+
+ debug('<br /><span class="pass">TEST COMPLETE</span>');
+ if (window.layoutTestController)
+ layoutTestController.waitUntilDone();
+ if (window.layoutTestController) {
+ layoutTestController.notifyDone();
+ }
+}
+</script>
+</head>
+<body onload="init()">
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas1"></canvas>
+<canvas id="canvas2"></canvas>
+<img id="img" src="http://localhost:8000/local/resources/abe.png" style="display:none;">
+<video id="video" style="display:none;"/>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-expected.txt b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-expected.txt
new file mode 100644
index 0000000..75cf15a
--- /dev/null
+++ b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-expected.txt
@@ -0,0 +1,15 @@
+Untainted canvas:
+PASS: Calling getImageData() from an untainted canvas was allowed.
+PASS: Calling toDataURL() on an untainted canvas was allowed.
+
+
+Tainted canvas:
+PASS: Calling getImageData() from a canvas tainted by a remote image was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a remote image was allowed.
+PASS: Calling getImageData() from a canvas tainted by a CORS-untained canvas was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a CORS-untained canvas was allowed.
+PASS: Calling getImageData() from a canvas tainted by a remote image tainted pattern was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a remote image tainted pattern was allowed.
+PASS: Calling getImageData() from a canvas tainted by a CORS-untainted canvas pattern was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a CORS-untainted canvas pattern was allowed.
+
diff --git a/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials-expected.txt b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials-expected.txt
new file mode 100644
index 0000000..75cf15a
--- /dev/null
+++ b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials-expected.txt
@@ -0,0 +1,15 @@
+Untainted canvas:
+PASS: Calling getImageData() from an untainted canvas was allowed.
+PASS: Calling toDataURL() on an untainted canvas was allowed.
+
+
+Tainted canvas:
+PASS: Calling getImageData() from a canvas tainted by a remote image was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a remote image was allowed.
+PASS: Calling getImageData() from a canvas tainted by a CORS-untained canvas was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a CORS-untained canvas was allowed.
+PASS: Calling getImageData() from a canvas tainted by a remote image tainted pattern was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a remote image tainted pattern was allowed.
+PASS: Calling getImageData() from a canvas tainted by a CORS-untainted canvas pattern was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a CORS-untainted canvas pattern was allowed.
+
diff --git a/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials.html b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials.html
new file mode 100644
index 0000000..a64ed5e
--- /dev/null
+++ b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials.html
@@ -0,0 +1,108 @@
+<pre id="console"></pre>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+log = function(msg)
+{
+ document.getElementById('console').appendChild(document.createTextNode(msg + "\n"));
+}
+
+testGetImageData = function(context, description)
+{
+ description = "Calling getImageData() from a canvas tainted by a " + description;
+ try {
+ var imageData = context.getImageData(0,0,100,100);
+ 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)
+{
+ testGetImageData(canvas.getContext("2d"), description);
+ testToDataURL(canvas, description);
+}
+
+var image = new Image();
+image.onload = function() {
+ var canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+
+ // Control tests
+ log("Untainted canvas:");
+ try {
+ var imageData = context.getImageData(0, 0, 100, 100);
+ log("PASS: Calling getImageData() from an untainted canvas was allowed.");
+ } catch (e) {
+ log("FAIL: Calling getImageData() 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 drawing a remote image onto it
+ context.drawImage(image, 0, 0, 100, 100);
+
+ test(canvas, "remote image");
+
+ var dirtyCanvas = canvas;
+
+ // Now test reading from a canvas after drawing a tainted canvas onto it
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ context.drawImage(dirtyCanvas, 0, 0, 100, 100);
+
+ test(canvas, "CORS-untained canvas");
+
+ // Test reading after using a tainted pattern
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ var remoteImagePattern = context.createPattern(image, "repeat");
+ context.fillStyle = remoteImagePattern;
+ context.fillRect(0, 0, 100, 100);
+
+ test(canvas, "remote image tainted pattern");
+
+ // Test reading after using a tainted pattern
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ var taintedCanvasPattern = context.createPattern(dirtyCanvas, "repeat");
+ context.fillStyle = taintedCanvasPattern;
+ context.fillRect(0, 0, 100, 100);
+
+ test(canvas, "CORS-untainted canvas pattern");
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+image.crossOrigin = "use-credentials";
+image.src = "http://localhost:8000/security/resources/abe-allow-credentials.php";
+</script>
diff --git a/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed.html b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed.html
new file mode 100644
index 0000000..610605f
--- /dev/null
+++ b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed.html
@@ -0,0 +1,108 @@
+<pre id="console"></pre>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+log = function(msg)
+{
+ document.getElementById('console').appendChild(document.createTextNode(msg + "\n"));
+}
+
+testGetImageData = function(context, description)
+{
+ description = "Calling getImageData() from a canvas tainted by a " + description;
+ try {
+ var imageData = context.getImageData(0,0,100,100);
+ 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)
+{
+ testGetImageData(canvas.getContext("2d"), description);
+ testToDataURL(canvas, description);
+}
+
+var image = new Image();
+image.onload = function() {
+ var canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+
+ // Control tests
+ log("Untainted canvas:");
+ try {
+ var imageData = context.getImageData(0, 0, 100, 100);
+ log("PASS: Calling getImageData() from an untainted canvas was allowed.");
+ } catch (e) {
+ log("FAIL: Calling getImageData() 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 drawing a remote image onto it
+ context.drawImage(image, 0, 0, 100, 100);
+
+ test(canvas, "remote image");
+
+ var dirtyCanvas = canvas;
+
+ // Now test reading from a canvas after drawing a tainted canvas onto it
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ context.drawImage(dirtyCanvas, 0, 0, 100, 100);
+
+ test(canvas, "CORS-untained canvas");
+
+ // Test reading after using a tainted pattern
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ var remoteImagePattern = context.createPattern(image, "repeat");
+ context.fillStyle = remoteImagePattern;
+ context.fillRect(0, 0, 100, 100);
+
+ test(canvas, "remote image tainted pattern");
+
+ // Test reading after using a tainted pattern
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ var taintedCanvasPattern = context.createPattern(dirtyCanvas, "repeat");
+ context.fillStyle = taintedCanvasPattern;
+ context.fillRect(0, 0, 100, 100);
+
+ test(canvas, "CORS-untainted canvas pattern");
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+image.crossOrigin = "anonymous";
+image.src = "http://localhost:8000/security/resources/abe-allow-star.php";
+</script>
diff --git a/LayoutTests/http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin-expected.txt b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin-expected.txt
new file mode 100644
index 0000000..aa3dde3
--- /dev/null
+++ b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin-expected.txt
@@ -0,0 +1,15 @@
+Untainted canvas:
+PASS: Calling getImageData() from an untainted canvas was allowed.
+PASS: Calling toDataURL() on an untainted canvas was allowed.
+
+
+Tainted canvas:
+PASS: Calling getImageData() from a canvas tainted by a remote image was not allowed - Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling toDataURL() on a canvas tainted by a remote image was not allowed - Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling getImageData() from a canvas tainted by a tained canvas was not allowed - Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling toDataURL() on a canvas tainted by a tained canvas was not allowed - Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling getImageData() from a canvas tainted by a remote image tainted pattern was not allowed - Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling toDataURL() on a canvas tainted by a remote image tainted pattern was not allowed - Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling getImageData() from a canvas tainted by a tainted canvas pattern was not allowed - Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling toDataURL() on a canvas tainted by a tainted canvas pattern was not allowed - Threw error: Error: SECURITY_ERR: DOM Exception 18.
+
diff --git a/LayoutTests/http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin.html b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin.html
new file mode 100644
index 0000000..4815683
--- /dev/null
+++ b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin.html
@@ -0,0 +1,108 @@
+<pre id="console"></pre>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+log = function(msg)
+{
+ document.getElementById('console').appendChild(document.createTextNode(msg + "\n"));
+}
+
+testGetImageData = function(context, description)
+{
+ description = "Calling getImageData() from a canvas tainted by a " + description;
+ try {
+ var imageData = context.getImageData(0,0,100,100);
+ log("FAIL: " + description + " was allowed.");
+ } catch (e) {
+ log("PASS: " + description + " was not allowed - Threw error: " + e + ".");
+ }
+}
+
+testToDataURL = function(canvas, description)
+{
+ description = "Calling toDataURL() on a canvas tainted by a " + description;
+ try {
+ var dataURL = canvas.toDataURL();
+ log("FAIL: " + description + " was allowed.");
+ } catch (e) {
+ log("PASS: " + description + " was not allowed - Threw error: " + e + ".");
+ }
+}
+
+test = function(canvas, description)
+{
+ testGetImageData(canvas.getContext("2d"), description);
+ testToDataURL(canvas, description);
+}
+
+var image = new Image();
+image.onload = function() {
+ var canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+
+ // Control tests
+ log("Untainted canvas:");
+ try {
+ var imageData = context.getImageData(0, 0, 100, 100);
+ log("PASS: Calling getImageData() from an untainted canvas was allowed.");
+ } catch (e) {
+ log("FAIL: Calling getImageData() 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 drawing a remote image onto it
+ context.drawImage(image, 0, 0, 100, 100);
+
+ test(canvas, "remote image");
+
+ var dirtyCanvas = canvas;
+
+ // Now test reading from a canvas after drawing a tainted canvas onto it
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ context.drawImage(dirtyCanvas, 0, 0, 100, 100);
+
+ test(canvas, "tained canvas");
+
+ // Test reading after using a tainted pattern
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ var remoteImagePattern = context.createPattern(image, "repeat");
+ context.fillStyle = remoteImagePattern;
+ context.fillRect(0, 0, 100, 100);
+
+ test(canvas, "remote image tainted pattern");
+
+ // Test reading after using a tainted pattern
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ var taintedCanvasPattern = context.createPattern(dirtyCanvas, "repeat");
+ context.fillStyle = taintedCanvasPattern;
+ context.fillRect(0, 0, 100, 100);
+
+ test(canvas, "tainted canvas pattern");
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+// Notice that we forget to set the image.crossOrigin property!
+image.src = "http://localhost:8000/security/resources/abe-allow-star.php";
+</script>
diff --git a/LayoutTests/http/tests/security/resources/abe-allow-credentials.php b/LayoutTests/http/tests/security/resources/abe-allow-credentials.php
new file mode 100644
index 0000000..2ca7408
--- /dev/null
+++ b/LayoutTests/http/tests/security/resources/abe-allow-credentials.php
@@ -0,0 +1,12 @@
+<?php
+header("Access-Control-Allow-Origin: http://127.0.0.1:8000");
+header("Access-Control-Allow-Credentials: true");
+
+$name = 'abe.png';
+$fp = fopen($name, 'rb');
+header("Content-Type: image/png");
+header("Content-Length: " . filesize($name));
+
+fpassthru($fp);
+exit;
+?>
diff --git a/LayoutTests/http/tests/security/resources/abe-allow-star.php b/LayoutTests/http/tests/security/resources/abe-allow-star.php
new file mode 100644
index 0000000..d3d621d
--- /dev/null
+++ b/LayoutTests/http/tests/security/resources/abe-allow-star.php
@@ -0,0 +1,11 @@
+<?php
+header("Access-Control-Allow-Origin: *");
+
+$name = 'abe.png';
+$fp = fopen($name, 'rb');
+header("Content-Type: image/png");
+header("Content-Length: " . filesize($name));
+
+fpassthru($fp);
+exit;
+?>
diff --git a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt
new file mode 100644
index 0000000..c86861c
--- /dev/null
+++ b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt
@@ -0,0 +1,13 @@
+Untainted canvas:
+PASS: Calling readPixels() from an untainted canvas was allowed.
+PASS: Calling toDataURL() on an untainted canvas was allowed.
+
+
+Tainted canvas:
+PASS: Calling texImage2D() with an untainted image was allowed
+PASS: Calling readPixels() from a canvas tainted by a remote image was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a remote image was allowed.
+PASS: Calling texImage2D() with an untainted canvas was allowed
+PASS: Calling readPixels() from a canvas tainted by a CORS-untained canvas was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a CORS-untained canvas was allowed.
+
diff --git a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt
new file mode 100644
index 0000000..c86861c
--- /dev/null
+++ b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt
@@ -0,0 +1,13 @@
+Untainted canvas:
+PASS: Calling readPixels() from an untainted canvas was allowed.
+PASS: Calling toDataURL() on an untainted canvas was allowed.
+
+
+Tainted canvas:
+PASS: Calling texImage2D() with an untainted image was allowed
+PASS: Calling readPixels() from a canvas tainted by a remote image was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a remote image was allowed.
+PASS: Calling texImage2D() with an untainted canvas was allowed
+PASS: Calling readPixels() from a canvas tainted by a CORS-untained canvas was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a CORS-untained canvas was allowed.
+
diff --git a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html
new file mode 100644
index 0000000..c09e37b
--- /dev/null
+++ b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html
@@ -0,0 +1,101 @@
+<pre id="console"></pre>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
+ layoutTestController.dumpAsText();
+ layoutTestController.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("experimental-webgl"), description);
+ testToDataURL(canvas, description);
+}
+
+var image = new Image();
+image.onload = function() {
+ var canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var gl = canvas.getContext("experimental-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 image as a texture
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ testTexImage2D(gl, image, "image");
+
+ test(canvas, "remote image");
+
+ // 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(image, 0, 0, 100, 100);
+ testTexImage2D(gl, dirtyCanvas, "canvas");
+
+ test(canvas, "CORS-untained canvas");
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+image.crossOrigin = "use-credentials";
+image.src = "http://localhost:8000/security/resources/abe-allow-credentials.php";
+</script>
diff --git a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed.html b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed.html
new file mode 100644
index 0000000..6448c2b
--- /dev/null
+++ b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed.html
@@ -0,0 +1,101 @@
+<pre id="console"></pre>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
+ layoutTestController.dumpAsText();
+ layoutTestController.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("experimental-webgl"), description);
+ testToDataURL(canvas, description);
+}
+
+var image = new Image();
+image.onload = function() {
+ var canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var gl = canvas.getContext("experimental-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 image as a texture
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ testTexImage2D(gl, image, "image");
+
+ test(canvas, "remote image");
+
+ // 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(image, 0, 0, 100, 100);
+ testTexImage2D(gl, dirtyCanvas, "canvas");
+
+ test(canvas, "CORS-untained canvas");
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+image.crossOrigin = "anonymous";
+image.src = "http://localhost:8000/security/resources/abe-allow-star.php";
+</script>
diff --git a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt
new file mode 100644
index 0000000..ee74457
--- /dev/null
+++ b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt
@@ -0,0 +1,13 @@
+Untainted canvas:
+PASS: Calling readPixels() from an untainted canvas was allowed.
+PASS: Calling toDataURL() on an untainted canvas was allowed.
+
+
+Tainted canvas:
+PASS: Calling texImage2D() with a tainted image was not allowed: Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling readPixels() on a canvas where tainting was attempted by a remote image was allowed.
+PASS: Calling toDataURL() on a canvas where tainting was attempted by a remote image was allowed.
+PASS: Calling texImage2D() with a tainted canvas was not allowed: Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling readPixels() on a canvas where tainting was attempted by a tainted canvas was allowed.
+PASS: Calling toDataURL() on a canvas where tainting was attempted by a tainted canvas was allowed.
+
diff --git a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html
new file mode 100644
index 0000000..f870c3e
--- /dev/null
+++ b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html
@@ -0,0 +1,103 @@
+<pre id="console"></pre>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+log = function(msg)
+{
+ document.getElementById('console').appendChild(document.createTextNode(msg + "\n"));
+}
+
+testTexImage2D = function(gl, source, description)
+{
+ description = "Calling texImage2D() with a tainted " + description;
+ try {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
+ log("FAIL: " + description + " was allowed");
+ } catch (e) {
+ log("PASS: " + description + " was not allowed: Threw error: " + e + ".");
+ }
+}
+
+testReadPixels = function(gl, description)
+{
+ description = "Calling readPixels() on a canvas where tainting was attempted 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 where tainting was attempted 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("experimental-webgl"), description);
+ testToDataURL(canvas, description);
+}
+
+var image = new Image();
+image.onload = function() {
+ var canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var gl = canvas.getContext("experimental-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 image as a texture
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ testTexImage2D(gl, image, "image");
+
+ test(canvas, "remote image");
+
+ var dirtyCanvas = canvas;
+
+ // Now test reading from a canvas after drawing a tainted canvas onto it
+ var dirtyCanvas = document.createElement("canvas");
+ dirtyCanvas.width = 100;
+ dirtyCanvas.height = 100;
+ var dirtyContext = dirtyCanvas.getContext("2d");
+ dirtyContext.drawImage(image, 0, 0, 100, 100);
+ testTexImage2D(gl, dirtyCanvas, "canvas");
+
+ test(canvas, "tainted canvas");
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+// Notice that we forget to set the image.crossOrigin property!
+image.src = "http://localhost:8000/security/resources/abe-allow-star.php";
+</script>