- a/LayoutTests/ChangeLog +19 lines
Lines 1-3 a/LayoutTests/ChangeLog_sec1
1
2011-06-09  Sheriff Bot  <webkit.review.bot@gmail.com>
2
3
        Unreviewed, rolling out r88387.
4
        http://trac.webkit.org/changeset/88387
5
        https://bugs.webkit.org/show_bug.cgi?id=62368
6
7
        New tests introduced in 88387 fail on Leopard,GTK,Qt bots
8
        (Requested by Ossy on #webkit).
9
10
        * http/tests/canvas/webgl/origin-clean-conformance-expected.txt:
11
        * http/tests/canvas/webgl/origin-clean-conformance.html:
12
        * http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt: Removed.
13
        * http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt: Removed.
14
        * http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html: Removed.
15
        * http/tests/security/webgl-remote-read-remote-image-allowed.html: Removed.
16
        * http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt: Removed.
17
        * http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html: Removed.
18
        * platform/mac-wk2/Skipped:
19
1
2011-06-09  Csaba Osztrogonác  <ossy@webkit.org>
20
2011-06-09  Csaba Osztrogonác  <ossy@webkit.org>
2
21
3
        [Qt] The profiler test is entirely unrelated to the original change r88337
22
        [Qt] The profiler test is entirely unrelated to the original change r88337
- a/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance-expected.txt -20 / +22 lines
Lines 1-29 a/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance-expected.txt_sec1
1
This test ensures WebGL implementations follow proper same-origin restrictions.
1
This test ensures WebGL implementations follow proper origin restrictions.
2
2
3
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
3
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
4
4
5
PASS Playable video format found
5
PASS Playable video format found
6
PASS img was loaded
6
PASS img was loaded
7
7
8
check that an attempt to upload an image from another origin throws an exception.
8
check that copying an img from another origin clears the origin-clean flag.
9
PASS texImage2D with cross-origin image should throw exception.
9
PASS should not throw exception by readPixels for origin clean canvas.
10
PASS texSubImage2D with cross-origin image should throw exception.
10
PASS should not throw exception by toDataURL for origin clean canvas.
11
check that readPixels and toDataURL continue to work against this canvas.
11
PASS should throw exception by readPixels for NON origin clean canvas.
12
PASS readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.
12
PASS should throw exception by toDataURL for NON origin clean canvas.
13
PASS should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.
13
14
check that an attempt to upload a tainted canvas throws an exception.
14
check that copying from 1 unclean 3d canvas to another clears the origin-clean flag on the second canvas.
15
PASS should not throw exception by readPixels for origin clean canvas.
16
PASS should not throw exception by toDataURL for origin clean canvas.
17
PASS should throw exception by readPixels for NON origin clean canvas.
18
PASS should throw exception by toDataURL for NON origin clean canvas.
19
20
check that copying from 1 unclean 3d canvas to a 2d canvas clears the origin-clean flag on the 2d canvas.
21
PASS should not throw exception by toDataURL for origin clean canvas.
22
PASS should throw exception by toDataURL for NON origin clean canvas.
23
24
check that copying a video from another origin clears the origin-clean flag.
25
PASS should not throw exception by readPixels for origin clean canvas.
26
PASS should not throw exception by toDataURL for origin clean canvas.
27
PASS should throw exception by readPixels for NON origin clean canvas.
15
PASS should throw exception by toDataURL for NON origin clean canvas.
28
PASS should throw exception by toDataURL for NON origin clean canvas.
16
PASS texImage2D with NON origin clean canvas should throw exception.
17
PASS texSubImage2D with NON origin clean canvas should throw exception.
18
check that readPixels and toDataURL continue to work against this canvas.
19
PASS readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.
20
PASS should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.
21
check that an attempt to upload a video from another origin throws an exception.
22
PASS texImage2D with cross-origin video should throw exception.
23
PASS texSubImage2D with cross-origin video should throw exception.
24
check that readPixels and toDataURL continue to work against this canvas.
25
PASS readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.
26
PASS should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.
27
29
28
TEST COMPLETE
30
TEST COMPLETE
29
 
31
   
- a/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html -60 / +61 lines
Lines 82-89 function causedException(func) { a/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html_sec1
82
  return hadException;
82
  return hadException;
83
}
83
}
84
84
85
var testVideo = false;
86
87
function init() {
85
function init() {
88
  var video = document.getElementById("video");
86
  var video = document.getElementById("video");
89
87
Lines 110-116 function init() { a/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html_sec2
110
    video.src = videoFile;
108
    video.src = videoFile;
111
    video.addEventListener("playing", runTests);
109
    video.addEventListener("playing", runTests);
112
    video.play();
110
    video.play();
113
    testVideo = true;
114
  } else {
111
  } else {
115
    // Still run the other tests, even if the video failed.
112
    // Still run the other tests, even if the video failed.
116
    runTests();
113
    runTests();
Lines 118-139 function init() { a/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html_sec3
118
}
115
}
119
116
120
function runTests() {
117
function runTests() {
121
  description("This test ensures WebGL implementations follow proper same-origin restrictions.");
118
  description("This test ensures WebGL implementations follow proper origin restrictions.");
122
  var img = document.getElementById("img");
119
  var img = document.getElementById("img");
123
  assertMsg(img.width > 0 && img.height > 0, "img was loaded");
120
  assertMsg(img.width > 0 && img.height > 0, "img was loaded");
124
121
125
  function makeTexImage2D(gl, src) {
126
    return function() {
127
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);
128
    };
129
  }
130
131
  function makeTexSubImage2D(gl, src) {
132
    return function() {
133
      gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src);
134
    };
135
  }
136
137
  function makeReadPixels(gl) {
122
  function makeReadPixels(gl) {
138
    return function() {
123
    return function() {
139
      var buf = new Uint8Array(4);
124
      var buf = new Uint8Array(4);
Lines 147-202 function runTests() { a/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html_sec4
147
    }
132
    }
148
  }
133
  }
149
134
150
  var canvas1 = document.getElementById("canvas1");
151
  var gl = create3DContext(canvas1);
152
153
  debug("");
135
  debug("");
154
  debug("check that an attempt to upload an image from another origin throws an exception.");
136
  debug("check that copying an img from another origin clears the origin-clean flag.");
155
  var tex = gl.createTexture();
137
  var canvas1 = document.getElementById("canvas1");
156
  gl.bindTexture(gl.TEXTURE_2D, tex);
138
  var gl1 = create3DContext(canvas1);
157
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 256, 256, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
139
  assertMsg(!causedException(makeReadPixels(gl1)),
158
  assertMsg(causedException(makeTexImage2D(gl, img)),
140
            "should not throw exception by readPixels for origin clean canvas.");
159
            "texImage2D with cross-origin image should throw exception.");
160
  assertMsg(causedException(makeTexSubImage2D(gl, img)),
161
            "texSubImage2D with cross-origin image should throw exception.");
162
163
  debug("check that readPixels and toDataURL continue to work against this canvas.");
164
  assertMsg(!causedException(makeReadPixels(gl)),
165
            "readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.");
166
  assertMsg(!causedException(makeToDataURL(canvas1)),
141
  assertMsg(!causedException(makeToDataURL(canvas1)),
167
            "should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.");
142
            "should not throw exception by toDataURL for origin clean canvas.");
143
144
  var tex = gl1.createTexture();
145
  gl1.bindTexture(gl1.TEXTURE_2D, tex);
146
  gl1.texImage2D(gl1.TEXTURE_2D, 0, gl1.RGBA, gl1.RGBA, gl1.UNSIGNED_BYTE, img);
168
147
169
  debug("check that an attempt to upload a tainted canvas throws an exception.");
148
  assertMsg(causedException(makeReadPixels(gl1)),
149
            "should throw exception by readPixels for NON origin clean canvas.");
150
  assertMsg(causedException(makeToDataURL(canvas1)),
151
            "should throw exception by toDataURL for NON origin clean canvas.");
152
153
  debug("");
154
  debug("check that copying from 1 unclean 3d canvas to another clears the origin-clean flag on the second canvas.");
170
  var canvas2 = document.getElementById("canvas2");
155
  var canvas2 = document.getElementById("canvas2");
171
  var ctx2d = canvas2.getContext("2d");
156
  var gl2 = create3DContext(canvas2);
172
  ctx2d.drawImage(img, 0, 0);
157
158
  assertMsg(!causedException(makeReadPixels(gl2)),
159
            "should not throw exception by readPixels for origin clean canvas.");
160
  assertMsg(!causedException(makeToDataURL(canvas2)),
161
            "should not throw exception by toDataURL for origin clean canvas.");
162
163
  var tex = gl2.createTexture();
164
  gl2.bindTexture(gl2.TEXTURE_2D, tex);
165
  gl2.texImage2D(
166
     gl2.TEXTURE_2D, 0, gl2.RGBA, gl2.RGBA, gl2.UNSIGNED_BYTE, canvas1);
167
168
  assertMsg(causedException(makeReadPixels(gl2)),
169
            "should throw exception by readPixels for NON origin clean canvas.");
173
  assertMsg(causedException(makeToDataURL(canvas2)),
170
  assertMsg(causedException(makeToDataURL(canvas2)),
174
            "should throw exception by toDataURL for NON origin clean canvas.");
171
            "should throw exception by toDataURL for NON origin clean canvas.");
175
  assertMsg(causedException(makeTexImage2D(gl, canvas2)),
172
176
            "texImage2D with NON origin clean canvas should throw exception.");
173
  debug("");
177
  assertMsg(causedException(makeTexSubImage2D(gl, canvas2)),
174
  debug("check that copying from 1 unclean 3d canvas to a 2d canvas clears the origin-clean flag on the 2d canvas.");
178
            "texSubImage2D with NON origin clean canvas should throw exception.");
175
  var canvas3 = document.getElementById("canvas3");
179
176
  var ctx2d = canvas3.getContext("2d");
180
  debug("check that readPixels and toDataURL continue to work against this canvas.");
177
  assertMsg(!causedException(makeToDataURL(canvas3)),
181
  assertMsg(!causedException(makeReadPixels(gl)),
178
            "should not throw exception by toDataURL for origin clean canvas.");
182
            "readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.");
179
  ctx2d.drawImage(canvas2, 0, 0);
183
  assertMsg(!causedException(makeToDataURL(canvas1)),
180
  assertMsg(causedException(makeToDataURL(canvas3)),
184
            "should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.");
181
            "should throw exception by toDataURL for NON origin clean canvas.");
185
182
186
  if (testVideo) {
183
  debug("");
187
    debug("check that an attempt to upload a video from another origin throws an exception.");
184
  debug("check that copying a video from another origin clears the origin-clean flag.");
188
    var video = document.getElementById("video");
185
  var canvas4 = document.getElementById("canvas4");
189
    assertMsg(causedException(makeTexImage2D(gl, video)),
186
  var gl4 = create3DContext(canvas4);
190
              "texImage2D with cross-origin video should throw exception.");
187
  assertMsg(!causedException(makeReadPixels(gl4)),
191
    assertMsg(causedException(makeTexSubImage2D(gl, video)),
188
            "should not throw exception by readPixels for origin clean canvas.");
192
              "texSubImage2D with cross-origin video should throw exception.");
189
  assertMsg(!causedException(makeToDataURL(canvas4)),
193
190
            "should not throw exception by toDataURL for origin clean canvas.");
194
    debug("check that readPixels and toDataURL continue to work against this canvas.");
191
  var tex4 = gl4.createTexture();
195
    assertMsg(!causedException(makeReadPixels(gl)),
192
  gl4.bindTexture(gl4.TEXTURE_2D, tex4);
196
              "readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.");
193
  gl4.texImage2D(
197
    assertMsg(!causedException(makeToDataURL(canvas1)),
194
      gl4.TEXTURE_2D, 0, gl4.RGBA, gl4.RGBA, gl4.UNSIGNED_BYTE, video);
198
              "should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.");
195
  assertMsg(causedException(makeReadPixels(gl4)),
199
  }
196
            "should throw exception by readPixels for NON origin clean canvas.");
197
  assertMsg(causedException(makeToDataURL(canvas4)),
198
            "should throw exception by toDataURL for NON origin clean canvas.");
200
199
201
  debug('<br /><span class="pass">TEST COMPLETE</span>');
200
  debug('<br /><span class="pass">TEST COMPLETE</span>');
202
  if (window.layoutTestController)
201
  if (window.layoutTestController)
Lines 212-217 function runTests() { a/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html_sec5
212
<div id="console"></div>
211
<div id="console"></div>
213
<canvas id="canvas1"></canvas>
212
<canvas id="canvas1"></canvas>
214
<canvas id="canvas2"></canvas>
213
<canvas id="canvas2"></canvas>
214
<canvas id="canvas3"></canvas>
215
<canvas id="canvas4"></canvas>
215
<img id="img" src="http://localhost:8000/local/resources/abe.png" style="display:none;">
216
<img id="img" src="http://localhost:8000/local/resources/abe.png" style="display:none;">
216
<video id="video" style="display:none;"/>
217
<video id="video" style="display:none;"/>
217
</body>
218
</body>
- a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt -13 lines
Lines 1-13 a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt_sec1
1
Untainted canvas:
2
PASS: Calling readPixels() from an untainted canvas was allowed.
3
PASS: Calling toDataURL() on an untainted canvas was allowed.
4
5
6
Tainted canvas:
7
PASS: Calling texImage2D() with an untainted image was allowed
8
PASS: Calling readPixels() from a canvas tainted by a remote image was allowed.
9
PASS: Calling toDataURL() on a canvas CORS-untainted by a remote image was allowed.
10
PASS: Calling texImage2D() with an untainted canvas was allowed
11
PASS: Calling readPixels() from a canvas tainted by a CORS-untained canvas was allowed.
12
PASS: Calling toDataURL() on a canvas CORS-untainted by a CORS-untained canvas was allowed.
13
- a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt -13 lines
Lines 1-13 a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt_sec1
1
Untainted canvas:
2
PASS: Calling readPixels() from an untainted canvas was allowed.
3
PASS: Calling toDataURL() on an untainted canvas was allowed.
4
5
6
Tainted canvas:
7
PASS: Calling texImage2D() with an untainted image was allowed
8
PASS: Calling readPixels() from a canvas tainted by a remote image was allowed.
9
PASS: Calling toDataURL() on a canvas CORS-untainted by a remote image was allowed.
10
PASS: Calling texImage2D() with an untainted canvas was allowed
11
PASS: Calling readPixels() from a canvas tainted by a CORS-untained canvas was allowed.
12
PASS: Calling toDataURL() on a canvas CORS-untainted by a CORS-untained canvas was allowed.
13
- a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html -101 lines
Lines 1-101 a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html_sec1
1
<pre id="console"></pre>
2
<script>
3
if (window.layoutTestController) {
4
    layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
5
    layoutTestController.dumpAsText();
6
    layoutTestController.waitUntilDone();
7
}
8
9
log = function(msg)
10
{
11
    document.getElementById('console').appendChild(document.createTextNode(msg + "\n"));
12
}
13
14
testTexImage2D = function(gl, source, description)
15
{
16
    description = "Calling texImage2D() with an untainted " + description;
17
    try {
18
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
19
        log("PASS: " + description + " was allowed");
20
    } catch (e) {
21
        log("FAIL: " + description + " was not allowed: Threw error: " + e + ".");
22
    }
23
}
24
25
testReadPixels = function(gl, description)
26
{
27
    description = "Calling readPixels() from a canvas tainted by a " + description;
28
    try {
29
        var pixels = new Uint8Array(4);
30
        gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
31
        log("PASS: " + description + " was allowed.");
32
    } catch (e) {
33
        log("FAIL: " + description + " was not allowed - Threw error: " + e + ".");
34
    }
35
}
36
37
testToDataURL = function(canvas, description)
38
{
39
    description = "Calling toDataURL() on a canvas CORS-untainted by a " + description;
40
    try {
41
        var dataURL = canvas.toDataURL();
42
        log("PASS: " + description + " was allowed.");
43
    } catch (e) {
44
        log("FAIL: " + description + " was not allowed - Threw error: " + e + ".");
45
    }
46
}
47
48
test = function(canvas, description)
49
{
50
    testReadPixels(canvas.getContext("experimental-webgl"), description);
51
    testToDataURL(canvas, description);
52
}
53
54
var image = new Image();
55
image.onload = function() {
56
    var canvas = document.createElement("canvas");
57
    canvas.width = 100;
58
    canvas.height = 100;
59
    var gl = canvas.getContext("experimental-webgl");
60
61
    // Control tests
62
    log("Untainted canvas:");
63
    try {
64
        var pixels = new Uint8Array(4);
65
        gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
66
        log("PASS: Calling readPixels() from an untainted canvas was allowed.");
67
    } catch (e) {
68
        log("FAIL: Calling readPixels() from an untainted canvas was not allowed: Threw error: " + e + ".");
69
    }
70
    try {
71
        var dataURL = canvas.toDataURL();
72
        log("PASS: Calling toDataURL() on an untainted canvas was allowed.");
73
    } catch (e) {
74
        log("FAIL: Calling toDataURL() on an untainted canvas was not allowed: Threw error: " + e + ".");
75
    }
76
77
    log("\n");
78
    log("Tainted canvas:");
79
    // Test reading from a canvas after uploading a remote image as a texture
80
    var texture = gl.createTexture();
81
    gl.bindTexture(gl.TEXTURE_2D, texture);
82
    testTexImage2D(gl, image, "image");
83
84
    test(canvas, "remote image");
85
86
    // Now test reading from a canvas after uploading a tainted canvas onto it
87
    var dirtyCanvas = document.createElement("canvas");
88
    dirtyCanvas.width = 100;
89
    dirtyCanvas.height = 100;
90
    var dirtyContext = dirtyCanvas.getContext("2d");
91
    dirtyContext.drawImage(image, 0, 0, 100, 100);
92
    testTexImage2D(gl, dirtyCanvas, "canvas");
93
94
    test(canvas, "CORS-untained canvas");
95
96
    if (window.layoutTestController)
97
        layoutTestController.notifyDone();
98
}
99
image.crossOrigin = "use-credentials";
100
image.src = "http://localhost:8000/security/resources/abe-allow-credentials.php";
101
</script>
- a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed.html -101 lines
Lines 1-101 a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed.html_sec1
1
<pre id="console"></pre>
2
<script>
3
if (window.layoutTestController) {
4
    layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
5
    layoutTestController.dumpAsText();
6
    layoutTestController.waitUntilDone();
7
}
8
9
log = function(msg)
10
{
11
    document.getElementById('console').appendChild(document.createTextNode(msg + "\n"));
12
}
13
14
testTexImage2D = function(gl, source, description)
15
{
16
    description = "Calling texImage2D() with an untainted " + description;
17
    try {
18
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
19
        log("PASS: " + description + " was allowed");
20
    } catch (e) {
21
        log("FAIL: " + description + " was not allowed: Threw error: " + e + ".");
22
    }
23
}
24
25
testReadPixels = function(gl, description)
26
{
27
    description = "Calling readPixels() from a canvas tainted by a " + description;
28
    try {
29
        var pixels = new Uint8Array(4);
30
        gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
31
        log("PASS: " + description + " was allowed.");
32
    } catch (e) {
33
        log("FAIL: " + description + " was not allowed - Threw error: " + e + ".");
34
    }
35
}
36
37
testToDataURL = function(canvas, description)
38
{
39
    description = "Calling toDataURL() on a canvas CORS-untainted by a " + description;
40
    try {
41
        var dataURL = canvas.toDataURL();
42
        log("PASS: " + description + " was allowed.");
43
    } catch (e) {
44
        log("FAIL: " + description + " was not allowed - Threw error: " + e + ".");
45
    }
46
}
47
48
test = function(canvas, description)
49
{
50
    testReadPixels(canvas.getContext("experimental-webgl"), description);
51
    testToDataURL(canvas, description);
52
}
53
54
var image = new Image();
55
image.onload = function() {
56
    var canvas = document.createElement("canvas");
57
    canvas.width = 100;
58
    canvas.height = 100;
59
    var gl = canvas.getContext("experimental-webgl");
60
61
    // Control tests
62
    log("Untainted canvas:");
63
    try {
64
        var pixels = new Uint8Array(4);
65
        gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
66
        log("PASS: Calling readPixels() from an untainted canvas was allowed.");
67
    } catch (e) {
68
        log("FAIL: Calling readPixels() from an untainted canvas was not allowed: Threw error: " + e + ".");
69
    }
70
    try {
71
        var dataURL = canvas.toDataURL();
72
        log("PASS: Calling toDataURL() on an untainted canvas was allowed.");
73
    } catch (e) {
74
        log("FAIL: Calling toDataURL() on an untainted canvas was not allowed: Threw error: " + e + ".");
75
    }
76
77
    log("\n");
78
    log("Tainted canvas:");
79
    // Test reading from a canvas after uploading a remote image as a texture
80
    var texture = gl.createTexture();
81
    gl.bindTexture(gl.TEXTURE_2D, texture);
82
    testTexImage2D(gl, image, "image");
83
84
    test(canvas, "remote image");
85
86
    // Now test reading from a canvas after uploading a tainted canvas onto it
87
    var dirtyCanvas = document.createElement("canvas");
88
    dirtyCanvas.width = 100;
89
    dirtyCanvas.height = 100;
90
    var dirtyContext = dirtyCanvas.getContext("2d");
91
    dirtyContext.drawImage(image, 0, 0, 100, 100);
92
    testTexImage2D(gl, dirtyCanvas, "canvas");
93
94
    test(canvas, "CORS-untained canvas");
95
96
    if (window.layoutTestController)
97
        layoutTestController.notifyDone();
98
}
99
image.crossOrigin = "anonymous";
100
image.src = "http://localhost:8000/security/resources/abe-allow-star.php";
101
</script>
- a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt -13 lines
Lines 1-13 a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt_sec1
1
Untainted canvas:
2
PASS: Calling readPixels() from an untainted canvas was allowed.
3
PASS: Calling toDataURL() on an untainted canvas was allowed.
4
5
6
Tainted canvas:
7
PASS: Calling texImage2D() with a tainted image was not allowed: Threw error: Error: SECURITY_ERR: DOM Exception 18.
8
PASS: Calling readPixels() on a canvas where tainting was attempted by a remote image was allowed.
9
PASS: Calling toDataURL() on a canvas where tainting was attempted by a remote image was allowed.
10
PASS: Calling texImage2D() with a tainted canvas was not allowed: Threw error: Error: SECURITY_ERR: DOM Exception 18.
11
PASS: Calling readPixels() on a canvas where tainting was attempted by a tainted canvas was allowed.
12
PASS: Calling toDataURL() on a canvas where tainting was attempted by a tainted canvas was allowed.
13
- a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html -103 lines
Lines 1-103 a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html_sec1
1
<pre id="console"></pre>
2
<script>
3
if (window.layoutTestController) {
4
    layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
5
    layoutTestController.dumpAsText();
6
    layoutTestController.waitUntilDone();
7
}
8
9
log = function(msg)
10
{
11
    document.getElementById('console').appendChild(document.createTextNode(msg + "\n"));
12
}
13
14
testTexImage2D = function(gl, source, description)
15
{
16
    description = "Calling texImage2D() with a tainted " + description;
17
    try {
18
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
19
        log("FAIL: " + description + " was allowed");
20
    } catch (e) {
21
        log("PASS: " + description + " was not allowed: Threw error: " + e + ".");
22
    }
23
}
24
25
testReadPixels = function(gl, description)
26
{
27
    description = "Calling readPixels() on a canvas where tainting was attempted by a " + description;
28
    try {
29
        var pixels = new Uint8Array(4);
30
        gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
31
        log("PASS: " + description + " was allowed.");
32
    } catch (e) {
33
        log("FAIL: " + description + " was not allowed - Threw error: " + e + ".");
34
    }
35
}
36
37
testToDataURL = function(canvas, description)
38
{
39
    description = "Calling toDataURL() on a canvas where tainting was attempted by a " + description;
40
    try {
41
        var dataURL = canvas.toDataURL();
42
        log("PASS: " + description + " was allowed.");
43
    } catch (e) {
44
        log("FAIL: " + description + " was not allowed - Threw error: " + e + ".");
45
    }
46
}
47
48
test = function(canvas, description)
49
{
50
    testReadPixels(canvas.getContext("experimental-webgl"), description);
51
    testToDataURL(canvas, description);
52
}
53
54
var image = new Image();
55
image.onload = function() {
56
    var canvas = document.createElement("canvas");
57
    canvas.width = 100;
58
    canvas.height = 100;
59
    var gl = canvas.getContext("experimental-webgl");
60
61
    // Control tests
62
    log("Untainted canvas:");
63
    try {
64
        var pixels = new Uint8Array(4);
65
        gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
66
        log("PASS: Calling readPixels() from an untainted canvas was allowed.");
67
    } catch (e) {
68
        log("FAIL: Calling readPixels() from an untainted canvas was not allowed: Threw error: " + e + ".");
69
    }
70
    try {
71
        var dataURL = canvas.toDataURL();
72
        log("PASS: Calling toDataURL() on an untainted canvas was allowed.");
73
    } catch (e) {
74
        log("FAIL: Calling toDataURL() on an untainted canvas was not allowed: Threw error: " + e + ".");
75
    }
76
77
    log("\n");
78
    log("Tainted canvas:");
79
    // Test reading from a canvas after uploading a remote image as a texture
80
    var texture = gl.createTexture();
81
    gl.bindTexture(gl.TEXTURE_2D, texture);
82
    testTexImage2D(gl, image, "image");
83
84
    test(canvas, "remote image");
85
86
    var dirtyCanvas = canvas;
87
88
    // Now test reading from a canvas after drawing a tainted canvas onto it
89
    var dirtyCanvas = document.createElement("canvas");
90
    dirtyCanvas.width = 100;
91
    dirtyCanvas.height = 100;
92
    var dirtyContext = dirtyCanvas.getContext("2d");
93
    dirtyContext.drawImage(image, 0, 0, 100, 100);
94
    testTexImage2D(gl, dirtyCanvas, "canvas");
95
96
    test(canvas, "tainted canvas");
97
98
    if (window.layoutTestController)
99
        layoutTestController.notifyDone();
100
}
101
// Notice that we forget to set the image.crossOrigin property!
102
image.src = "http://localhost:8000/security/resources/abe-allow-star.php";
103
</script>
- a/LayoutTests/platform/mac-wk2/Skipped -3 lines
Lines 984-992 http/tests/inspector/network/ping.html a/LayoutTests/platform/mac-wk2/Skipped_sec1
984
http/tests/navigation/ping-cross-origin-from-https.html
984
http/tests/navigation/ping-cross-origin-from-https.html
985
http/tests/navigation/ping-cross-origin.html
985
http/tests/navigation/ping-cross-origin.html
986
http/tests/navigation/ping-same-origin.html
986
http/tests/navigation/ping-same-origin.html
987
http/tests/security/webgl-remote-read-remote-image-allowed.html
988
http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html
989
http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html
990
loader/go-back-to-different-window-size.html
987
loader/go-back-to-different-window-size.html
991
media/restore-from-page-cache.html
988
media/restore-from-page-cache.html
992
java/embedding-java-with-object.html
989
java/embedding-java-with-object.html
- a/Source/WebCore/ChangeLog +19 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2011-06-09  Sheriff Bot  <webkit.review.bot@gmail.com>
2
3
        Unreviewed, rolling out r88387.
4
        http://trac.webkit.org/changeset/88387
5
        https://bugs.webkit.org/show_bug.cgi?id=62368
6
7
        New tests introduced in 88387 fail on Leopard,GTK,Qt bots
8
        (Requested by Ossy on #webkit).
9
10
        * html/canvas/CanvasRenderingContext.cpp:
11
        (WebCore::CanvasRenderingContext::checkOrigin):
12
        * html/canvas/CanvasRenderingContext.h:
13
        * html/canvas/WebGLRenderingContext.cpp:
14
        (WebCore::WebGLRenderingContext::readPixels):
15
        (WebCore::WebGLRenderingContext::texImage2D):
16
        (WebCore::WebGLRenderingContext::videoFrameToImage):
17
        (WebCore::WebGLRenderingContext::texSubImage2D):
18
        * html/canvas/WebGLRenderingContext.h:
19
1
2011-06-09  Adam Barth  <abarth@webkit.org>
20
2011-06-09  Adam Barth  <abarth@webkit.org>
2
21
3
        Reviewed by Eric Seidel.
22
        Reviewed by Eric Seidel.
- a/Source/WebCore/html/canvas/CanvasRenderingContext.cpp -39 / +19 lines
Lines 41-113 CanvasRenderingContext::CanvasRenderingContext(HTMLCanvasElement* canvas) a/Source/WebCore/html/canvas/CanvasRenderingContext.cpp_sec1
41
{
41
{
42
}
42
}
43
43
44
bool CanvasRenderingContext::wouldTaintOrigin(const CanvasPattern* pattern)
44
void CanvasRenderingContext::checkOrigin(const CanvasPattern* pattern)
45
{
45
{
46
    if (canvas()->originClean() && pattern && !pattern->originClean())
46
    if (canvas()->originClean() && pattern && !pattern->originClean())
47
        return true;
47
        canvas()->setOriginTainted();
48
    return false;
49
}
48
}
50
49
51
bool CanvasRenderingContext::wouldTaintOrigin(const HTMLCanvasElement* sourceCanvas)
50
void CanvasRenderingContext::checkOrigin(const HTMLCanvasElement* sourceCanvas)
52
{
51
{
53
    if (canvas()->originClean() && sourceCanvas && !sourceCanvas->originClean())
52
    if (canvas()->originClean() && sourceCanvas && !sourceCanvas->originClean())
54
        return true;
53
        canvas()->setOriginTainted();
55
    return false;
56
}
54
}
57
55
58
bool CanvasRenderingContext::wouldTaintOrigin(const HTMLImageElement* image)
56
void CanvasRenderingContext::checkOrigin(const HTMLImageElement* image)
59
{
57
{
60
    if (!image || !canvas()->originClean())
58
    if (!image || !canvas()->originClean())
61
        return false;
59
        return;
62
60
63
    CachedImage* cachedImage = image->cachedImage();
61
    CachedImage* cachedImage = image->cachedImage();
64
    if (!cachedImage->passesAccessControlCheck(canvas()->securityOrigin())) {
62
    if (!cachedImage->passesAccessControlCheck(canvas()->securityOrigin()))
65
        if (wouldTaintOrigin(cachedImage->response().url()))
63
        checkOrigin(cachedImage->response().url());
66
            return true;
67
    }
68
64
69
    if (!cachedImage->image()->hasSingleSecurityOrigin())
65
    if (canvas()->originClean() && !cachedImage->image()->hasSingleSecurityOrigin())
70
        return true;
66
        canvas()->setOriginTainted();
71
72
    return false;
73
}
67
}
74
68
75
bool CanvasRenderingContext::wouldTaintOrigin(const HTMLVideoElement* video)
69
void CanvasRenderingContext::checkOrigin(const HTMLVideoElement* video)
76
{
70
{
77
#if ENABLE(VIDEO)
71
#if ENABLE(VIDEO)
78
    // FIXME: This check is likely wrong when a redirect is involved. We need
72
    // FIXME: This check is likely wrong when a redirect is involved. We need
79
    // to test the finalURL. Please be careful when fixing this issue not to
73
    // to test the finalURL. Please be careful when fixing this issue not to
80
    // make currentSrc be the final URL because then the
74
    // make currentSrc be the final URL because then the
81
    // HTMLMediaElement.currentSrc DOM API would leak redirect destinations!
75
    // HTMLMediaElement.currentSrc DOM API would leak redirect destinations!
82
    if (!video || !canvas()->originClean())
76
    checkOrigin(video->currentSrc());
83
        return false;
77
    if (canvas()->originClean() && video && !video->hasSingleSecurityOrigin())
84
78
        canvas()->setOriginTainted();
85
    if (wouldTaintOrigin(video->currentSrc()))
86
        return true;
87
88
    if (!video->hasSingleSecurityOrigin())
89
        return true;
90
#endif
79
#endif
91
92
    return false;
93
}
80
}
94
81
95
bool CanvasRenderingContext::wouldTaintOrigin(const KURL& url)
82
void CanvasRenderingContext::checkOrigin(const KURL& url)
96
{
83
{
97
    if (!canvas()->originClean() || m_cleanURLs.contains(url.string()))
84
    if (!canvas()->originClean() || m_cleanOrigins.contains(url.string()))
98
        return false;
85
        return;
99
86
100
    if (canvas()->securityOrigin()->taintsCanvas(url))
87
    if (canvas()->securityOrigin()->taintsCanvas(url))
101
        return true;
102
103
    m_cleanURLs.add(url.string());
104
    return false;
105
}
106
107
void CanvasRenderingContext::checkOrigin(const KURL& url)
108
{
109
    if (wouldTaintOrigin(url))
110
        canvas()->setOriginTainted();
88
        canvas()->setOriginTainted();
89
    else
90
        m_cleanOrigins.add(url.string());
111
}
91
}
112
92
113
} // namespace WebCore
93
} // namespace WebCore
- a/Source/WebCore/html/canvas/CanvasRenderingContext.h -12 / +5 lines
Lines 63-84 public: a/Source/WebCore/html/canvas/CanvasRenderingContext.h_sec1
63
63
64
protected:
64
protected:
65
    CanvasRenderingContext(HTMLCanvasElement*);
65
    CanvasRenderingContext(HTMLCanvasElement*);
66
    bool wouldTaintOrigin(const CanvasPattern*);
66
    void checkOrigin(const CanvasPattern*);
67
    bool wouldTaintOrigin(const HTMLCanvasElement*);
67
    void checkOrigin(const HTMLCanvasElement*);
68
    bool wouldTaintOrigin(const HTMLImageElement*);
68
    void checkOrigin(const HTMLImageElement*);
69
    bool wouldTaintOrigin(const HTMLVideoElement*);
69
    void checkOrigin(const HTMLVideoElement*);
70
    bool wouldTaintOrigin(const KURL&);
71
72
    template<class T> void checkOrigin(const T* arg)
73
    {
74
        if (wouldTaintOrigin(arg))
75
            canvas()->setOriginTainted();
76
    }
77
    void checkOrigin(const KURL&);
70
    void checkOrigin(const KURL&);
78
71
79
private:
72
private:
80
    HTMLCanvasElement* m_canvas;
73
    HTMLCanvasElement* m_canvas;
81
    HashSet<String> m_cleanURLs;
74
    HashSet<String> m_cleanOrigins;
82
};
75
};
83
76
84
} // namespace WebCore
77
} // namespace WebCore
- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp -30 / +15 lines
Lines 2807-2819 void WebGLRenderingContext::polygonOffset(GC3Dfloat factor, GC3Dfloat units) a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp_sec1
2807
    cleanupAfterGraphicsCall(false);
2807
    cleanupAfterGraphicsCall(false);
2808
}
2808
}
2809
2809
2810
void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode&)
2810
void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec)
2811
{
2811
{
2812
    if (isContextLost())
2812
    if (isContextLost())
2813
        return;
2813
        return;
2814
    // Due to WebGL's same-origin restrictions, it is not possible to
2814
    if (!canvas()->originClean()) {
2815
    // taint the origin using the WebGL API.
2815
        ec = SECURITY_ERR;
2816
    ASSERT(canvas()->originClean());
2816
        return;
2817
    }
2817
    // Validate input parameters.
2818
    // Validate input parameters.
2818
    if (!pixels) {
2819
    if (!pixels) {
2819
        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2820
        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
Lines 3156-3166 void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp_sec2
3156
        return;
3157
        return;
3157
    if (!validateHTMLImageElement(image))
3158
    if (!validateHTMLImageElement(image))
3158
        return;
3159
        return;
3159
    if (wouldTaintOrigin(image)) {
3160
    checkOrigin(image);
3160
        ec = SECURITY_ERR;
3161
        return;
3162
    }
3163
3164
    texImage2DImpl(target, level, internalformat, format, type, image->cachedImage()->image(),
3161
    texImage2DImpl(target, level, internalformat, format, type, image->cachedImage()->image(),
3165
                   m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
3162
                   m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
3166
}
3163
}
Lines 3175-3184 void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp_sec3
3175
        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3172
        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3176
        return;
3173
        return;
3177
    }
3174
    }
3178
    if (wouldTaintOrigin(canvas)) {
3175
    checkOrigin(canvas);
3179
        ec = SECURITY_ERR;
3180
        return;
3181
    }
3182
    RefPtr<ImageData> imageData = canvas->getImageData();
3176
    RefPtr<ImageData> imageData = canvas->getImageData();
3183
    if (imageData)
3177
    if (imageData)
3184
        texImage2D(target, level, internalformat, format, type, imageData.get(), ec);
3178
        texImage2D(target, level, internalformat, format, type, imageData.get(), ec);
Lines 3188-3194 void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp_sec4
3188
}
3182
}
3189
3183
3190
#if ENABLE(VIDEO)
3184
#if ENABLE(VIDEO)
3191
PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video, ExceptionCode& ec)
3185
PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video)
3192
{
3186
{
3193
    if (!video || !video->videoWidth() || !video->videoHeight()) {
3187
    if (!video || !video->videoWidth() || !video->videoHeight()) {
3194
        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3188
        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
Lines 3200-3209 PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* vid a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp_sec5
3200
        m_context->synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY);
3194
        m_context->synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY);
3201
        return 0;
3195
        return 0;
3202
    }
3196
    }
3203
    if (wouldTaintOrigin(video)) {
3197
    checkOrigin(video);
3204
        ec = SECURITY_ERR;
3205
        return 0;
3206
    }
3207
    IntRect destRect(0, 0, size.width(), size.height());
3198
    IntRect destRect(0, 0, size.width(), size.height());
3208
    // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
3199
    // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
3209
    video->paintCurrentFrameInContext(buf->context(), destRect);
3200
    video->paintCurrentFrameInContext(buf->context(), destRect);
Lines 3216-3223 void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp_sec6
3216
    ec = 0;
3207
    ec = 0;
3217
    if (isContextLost())
3208
    if (isContextLost())
3218
        return;
3209
        return;
3219
    RefPtr<Image> image = videoFrameToImage(video, ec);
3210
    RefPtr<Image> image = videoFrameToImage(video);
3220
    if (!image)
3211
    if (!video)
3221
        return;
3212
        return;
3222
    texImage2DImpl(target, level, internalformat, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
3213
    texImage2DImpl(target, level, internalformat, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
3223
}
3214
}
Lines 3358-3367 void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp_sec7
3358
        return;
3349
        return;
3359
    if (!validateHTMLImageElement(image))
3350
    if (!validateHTMLImageElement(image))
3360
        return;
3351
        return;
3361
    if (wouldTaintOrigin(image)) {
3352
    checkOrigin(image);
3362
        ec = SECURITY_ERR;
3363
        return;
3364
    }
3365
    texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image->cachedImage()->image(),
3353
    texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image->cachedImage()->image(),
3366
                      m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
3354
                      m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
3367
}
3355
}
Lines 3376-3385 void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp_sec8
3376
        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3364
        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3377
        return;
3365
        return;
3378
    }
3366
    }
3379
    if (wouldTaintOrigin(canvas)) {
3367
    checkOrigin(canvas);
3380
        ec = SECURITY_ERR;
3381
        return;
3382
    }
3383
    RefPtr<ImageData> imageData = canvas->getImageData();
3368
    RefPtr<ImageData> imageData = canvas->getImageData();
3384
    if (imageData)
3369
    if (imageData)
3385
        texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), ec);
3370
        texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), ec);
Lines 3395-3402 void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp_sec9
3395
    ec = 0;
3380
    ec = 0;
3396
    if (isContextLost())
3381
    if (isContextLost())
3397
        return;
3382
        return;
3398
    RefPtr<Image> image = videoFrameToImage(video, ec);
3383
    RefPtr<Image> image = videoFrameToImage(video);
3399
    if (!image)
3384
    if (!video)
3400
        return;
3385
        return;
3401
    texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
3386
    texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
3402
}
3387
}
- a/Source/WebCore/html/canvas/WebGLRenderingContext.h -1 / +1 lines
Lines 344-350 public: a/Source/WebCore/html/canvas/WebGLRenderingContext.h_sec1
344
    bool validateWebGLObject(WebGLObject*);
344
    bool validateWebGLObject(WebGLObject*);
345
345
346
#if ENABLE(VIDEO)
346
#if ENABLE(VIDEO)
347
    PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, ExceptionCode&);
347
    PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*);
348
#endif
348
#endif
349
349
350
    RefPtr<GraphicsContext3D> m_context;
350
    RefPtr<GraphicsContext3D> m_context;

Return to Bug 62368