WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-62257-20110607193429.patch (text/plain), 39.02 KB, created by
Kenneth Russell
on 2011-06-07 19:34:31 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Kenneth Russell
Created:
2011-06-07 19:34:31 PDT
Size:
39.02 KB
patch
obsolete
>Index: Source/WebCore/ChangeLog >=================================================================== >--- Source/WebCore/ChangeLog (revision 88316) >+++ Source/WebCore/ChangeLog (working copy) >@@ -1,3 +1,27 @@ >+2011-06-07 Kenneth Russell <kbr@google.com> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Disallow use of cross-domain media (images, video) in WebGL >+ https://bugs.webkit.org/show_bug.cgi?id=62257 >+ >+ Updated WebGL implementation to track recent spec updates in this area. >+ >+ Tests: http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html >+ http/tests/security/webgl-remote-read-remote-image-allowed.html >+ http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html >+ >+ * html/canvas/CanvasRenderingContext.cpp: >+ (WebCore::CanvasRenderingContext::wouldTaintOrigin): >+ (WebCore::CanvasRenderingContext::checkOrigin): >+ * html/canvas/CanvasRenderingContext.h: >+ * html/canvas/WebGLRenderingContext.cpp: >+ (WebCore::WebGLRenderingContext::readPixels): >+ (WebCore::WebGLRenderingContext::texImage2D): >+ (WebCore::WebGLRenderingContext::videoFrameToImage): >+ (WebCore::WebGLRenderingContext::texSubImage2D): >+ * html/canvas/WebGLRenderingContext.h: >+ > 2011-06-07 Tim Horton <timothy_horton@apple.com> > > Reviewed by Alexey Proskuryakov. >Index: Source/WebCore/html/canvas/CanvasRenderingContext.cpp >=================================================================== >--- Source/WebCore/html/canvas/CanvasRenderingContext.cpp (revision 88316) >+++ Source/WebCore/html/canvas/CanvasRenderingContext.cpp (working copy) >@@ -41,53 +41,98 @@ CanvasRenderingContext::CanvasRenderingC > { > } > >-void CanvasRenderingContext::checkOrigin(const CanvasPattern* pattern) >+bool CanvasRenderingContext::wouldTaintOrigin(const CanvasPattern* pattern) > { > if (canvas()->originClean() && pattern && !pattern->originClean()) >- canvas()->setOriginTainted(); >+ return true; >+ return false; > } > >-void CanvasRenderingContext::checkOrigin(const HTMLCanvasElement* sourceCanvas) >+bool CanvasRenderingContext::wouldTaintOrigin(const HTMLCanvasElement* sourceCanvas) > { > if (canvas()->originClean() && sourceCanvas && !sourceCanvas->originClean()) >- canvas()->setOriginTainted(); >+ return true; >+ return false; > } > >-void CanvasRenderingContext::checkOrigin(const HTMLImageElement* image) >+bool CanvasRenderingContext::wouldTaintOrigin(const HTMLImageElement* image) > { > if (!image || !canvas()->originClean()) >- return; >+ return false; > > CachedImage* cachedImage = image->cachedImage(); >- if (!cachedImage->passesAccessControlCheck(canvas()->securityOrigin())) >- checkOrigin(cachedImage->response().url()); >+ if (!cachedImage->passesAccessControlCheck(canvas()->securityOrigin())) { >+ if (wouldTaintOrigin(cachedImage->response().url())) >+ return true; >+ } > >- if (canvas()->originClean() && !cachedImage->image()->hasSingleSecurityOrigin()) >- canvas()->setOriginTainted(); >+ if (!cachedImage->image()->hasSingleSecurityOrigin()) >+ return true; >+ >+ return false; > } > >-void CanvasRenderingContext::checkOrigin(const HTMLVideoElement* video) >+bool CanvasRenderingContext::wouldTaintOrigin(const HTMLVideoElement* video) > { > #if ENABLE(VIDEO) > // FIXME: This check is likely wrong when a redirect is involved. We need > // to test the finalURL. Please be careful when fixing this issue not to > // make currentSrc be the final URL because then the > // HTMLMediaElement.currentSrc DOM API would leak redirect destinations! >- checkOrigin(video->currentSrc()); >- if (canvas()->originClean() && video && !video->hasSingleSecurityOrigin()) >- canvas()->setOriginTainted(); >+ if (!video || !canvas()->originClean()) >+ return false; >+ >+ if (wouldTaintOrigin(video->currentSrc())) >+ return true; >+ >+ if (!video->hasSingleSecurityOrigin()) >+ return true; > #endif >+ >+ return false; > } > >-void CanvasRenderingContext::checkOrigin(const KURL& url) >+bool CanvasRenderingContext::wouldTaintOrigin(const KURL& url) > { > if (!canvas()->originClean() || m_cleanOrigins.contains(url.string())) >- return; >+ return false; > > if (canvas()->securityOrigin()->taintsCanvas(url)) >+ return true; >+ >+ m_cleanOrigins.add(url.string()); >+ return false; >+} >+ >+ >+void CanvasRenderingContext::checkOrigin(const CanvasPattern* pattern) >+{ >+ if (wouldTaintOrigin(pattern)) >+ canvas()->setOriginTainted(); >+} >+ >+void CanvasRenderingContext::checkOrigin(const HTMLCanvasElement* sourceCanvas) >+{ >+ if (wouldTaintOrigin(sourceCanvas)) >+ canvas()->setOriginTainted(); >+} >+ >+void CanvasRenderingContext::checkOrigin(const HTMLImageElement* image) >+{ >+ if (wouldTaintOrigin(image)) >+ canvas()->setOriginTainted(); >+} >+ >+void CanvasRenderingContext::checkOrigin(const HTMLVideoElement* video) >+{ >+ if (wouldTaintOrigin(video)) >+ canvas()->setOriginTainted(); >+} >+ >+void CanvasRenderingContext::checkOrigin(const KURL& url) >+{ >+ if (wouldTaintOrigin(url)) > canvas()->setOriginTainted(); >- else >- m_cleanOrigins.add(url.string()); > } > > } // namespace WebCore >Index: Source/WebCore/html/canvas/CanvasRenderingContext.h >=================================================================== >--- Source/WebCore/html/canvas/CanvasRenderingContext.h (revision 88316) >+++ Source/WebCore/html/canvas/CanvasRenderingContext.h (working copy) >@@ -63,6 +63,12 @@ public: > > protected: > CanvasRenderingContext(HTMLCanvasElement*); >+ bool wouldTaintOrigin(const CanvasPattern*); >+ bool wouldTaintOrigin(const HTMLCanvasElement*); >+ bool wouldTaintOrigin(const HTMLImageElement*); >+ bool wouldTaintOrigin(const HTMLVideoElement*); >+ bool wouldTaintOrigin(const KURL&); >+ > void checkOrigin(const CanvasPattern*); > void checkOrigin(const HTMLCanvasElement*); > void checkOrigin(const HTMLImageElement*); >Index: Source/WebCore/html/canvas/WebGLRenderingContext.cpp >=================================================================== >--- Source/WebCore/html/canvas/WebGLRenderingContext.cpp (revision 88316) >+++ Source/WebCore/html/canvas/WebGLRenderingContext.cpp (working copy) >@@ -2809,12 +2809,11 @@ void WebGLRenderingContext::polygonOffse > > void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec) > { >+ UNUSED_PARAM(ec); > if (isContextLost()) > return; >- if (!canvas()->originClean()) { >- ec = SECURITY_ERR; >- return; >- } >+ // It is no longer possible to taint the origin using the WebGL API. >+ ASSERT(canvas()->originClean()); > // Validate input parameters. > if (!pixels) { > m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); >@@ -3157,7 +3156,11 @@ void WebGLRenderingContext::texImage2D(G > return; > if (!validateHTMLImageElement(image)) > return; >- checkOrigin(image); >+ if (wouldTaintOrigin(image)) { >+ ec = SECURITY_ERR; >+ return; >+ } >+ > texImage2DImpl(target, level, internalformat, format, type, image->cachedImage()->image(), > m_unpackFlipY, m_unpackPremultiplyAlpha, ec); > } >@@ -3172,7 +3175,10 @@ void WebGLRenderingContext::texImage2D(G > m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); > return; > } >- checkOrigin(canvas); >+ if (wouldTaintOrigin(canvas)) { >+ ec = SECURITY_ERR; >+ return; >+ } > RefPtr<ImageData> imageData = canvas->getImageData(); > if (imageData) > texImage2D(target, level, internalformat, format, type, imageData.get(), ec); >@@ -3182,7 +3188,7 @@ void WebGLRenderingContext::texImage2D(G > } > > #if ENABLE(VIDEO) >-PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video) >+PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video, ExceptionCode& ec) > { > if (!video || !video->videoWidth() || !video->videoHeight()) { > m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); >@@ -3194,7 +3200,10 @@ PassRefPtr<Image> WebGLRenderingContext: > m_context->synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY); > return 0; > } >- checkOrigin(video); >+ if (wouldTaintOrigin(video)) { >+ ec = SECURITY_ERR; >+ return 0; >+ } > IntRect destRect(0, 0, size.width(), size.height()); > // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback. > video->paintCurrentFrameInContext(buf->context(), destRect); >@@ -3207,8 +3216,8 @@ void WebGLRenderingContext::texImage2D(G > ec = 0; > if (isContextLost()) > return; >- RefPtr<Image> image = videoFrameToImage(video); >- if (!video) >+ RefPtr<Image> image = videoFrameToImage(video, ec); >+ if (!image) > return; > texImage2DImpl(target, level, internalformat, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec); > } >@@ -3349,7 +3358,10 @@ void WebGLRenderingContext::texSubImage2 > return; > if (!validateHTMLImageElement(image)) > return; >- checkOrigin(image); >+ if (wouldTaintOrigin(image)) { >+ ec = SECURITY_ERR; >+ return; >+ } > texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image->cachedImage()->image(), > m_unpackFlipY, m_unpackPremultiplyAlpha, ec); > } >@@ -3364,7 +3376,10 @@ void WebGLRenderingContext::texSubImage2 > m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); > return; > } >- checkOrigin(canvas); >+ if (wouldTaintOrigin(canvas)) { >+ ec = SECURITY_ERR; >+ return; >+ } > RefPtr<ImageData> imageData = canvas->getImageData(); > if (imageData) > texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), ec); >@@ -3380,8 +3395,8 @@ void WebGLRenderingContext::texSubImage2 > ec = 0; > if (isContextLost()) > return; >- RefPtr<Image> image = videoFrameToImage(video); >- if (!video) >+ RefPtr<Image> image = videoFrameToImage(video, ec); >+ if (!image) > return; > texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec); > } >Index: Source/WebCore/html/canvas/WebGLRenderingContext.h >=================================================================== >--- Source/WebCore/html/canvas/WebGLRenderingContext.h (revision 88316) >+++ Source/WebCore/html/canvas/WebGLRenderingContext.h (working copy) >@@ -344,7 +344,7 @@ public: > bool validateWebGLObject(WebGLObject*); > > #if ENABLE(VIDEO) >- PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*); >+ PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, ExceptionCode&); > #endif > > RefPtr<GraphicsContext3D> m_context; >Index: LayoutTests/ChangeLog >=================================================================== >--- LayoutTests/ChangeLog (revision 88316) >+++ LayoutTests/ChangeLog (working copy) >@@ -1,3 +1,27 @@ >+2011-06-07 Kenneth Russell <kbr@google.com> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Disallow use of cross-domain media (images, video) in WebGL >+ https://bugs.webkit.org/show_bug.cgi?id=62257 >+ >+ Updated origin-clean-conformance.html to track upstream version in >+ Khronos repository. Added new layout tests mirroring those added >+ in bug 61015 which verify that new CORS support for images is >+ working in the context of WebGL. >+ >+ Verified new tests in WebKit and Chromium. >+ >+ * http/tests/canvas/webgl/origin-clean-conformance-expected.txt: >+ * http/tests/canvas/webgl/origin-clean-conformance.html: >+ * http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt: Added. >+ * http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt: Added. >+ * http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html: Added. >+ * http/tests/security/webgl-remote-read-remote-image-allowed.html: Added. >+ * http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt: Added. >+ * http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html: Added. >+ * platform/mac-wk2/Skipped: >+ > 2011-06-07 Gavin Barraclough <barraclough@apple.com> > > Reviewed by Sam Weinig. >Index: LayoutTests/http/tests/canvas/webgl/origin-clean-conformance-expected.txt >=================================================================== >--- LayoutTests/http/tests/canvas/webgl/origin-clean-conformance-expected.txt (revision 88316) >+++ LayoutTests/http/tests/canvas/webgl/origin-clean-conformance-expected.txt (working copy) >@@ -1,31 +1,29 @@ >-This test ensures WebGL implementations follow proper origin restrictions. >+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 copying an img from another origin clears the origin-clean flag. >-PASS should not throw exception by readPixels for origin clean canvas. >-PASS should not throw exception by toDataURL for origin clean canvas. >-PASS should throw exception by readPixels for NON origin clean canvas. >-PASS should throw exception by toDataURL for NON origin clean canvas. >- >-check that copying from 1 unclean 3d canvas to another clears the origin-clean flag on the second canvas. >-PASS should not throw exception by readPixels for origin clean canvas. >-PASS should not throw exception by toDataURL for origin clean canvas. >-PASS should throw exception by readPixels for NON origin clean canvas. >-PASS should throw exception by toDataURL for NON origin clean canvas. >- >-check that copying from 1 unclean 3d canvas to a 2d canvas clears the origin-clean flag on the 2d canvas. >-PASS should not throw exception by toDataURL for origin clean canvas. >-PASS should throw exception by toDataURL for NON origin clean canvas. >- >-check that copying a video from another origin clears the origin-clean flag. >-PASS should not throw exception by readPixels for origin clean canvas. >-PASS should not throw exception by toDataURL for origin clean canvas. >-PASS should throw exception by readPixels for NON origin clean canvas. >+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 >- >+ >Index: LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html >=================================================================== >--- LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html (revision 88316) >+++ LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html (working copy) >@@ -82,6 +82,8 @@ function causedException(func) { > return hadException; > } > >+var testVideo = false; >+ > function init() { > var video = document.getElementById("video"); > >@@ -108,6 +110,7 @@ function init() { > video.src = videoFile; > video.addEventListener("playing", runTests); > video.play(); >+ testVideo = true; > } else { > // Still run the other tests, even if the video failed. > runTests(); >@@ -115,10 +118,22 @@ function init() { > } > > function runTests() { >- description("This test ensures WebGL implementations follow proper origin restrictions."); >+ 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); >@@ -132,70 +147,56 @@ function runTests() { > } > } > >- debug(""); >- debug("check that copying an img from another origin clears the origin-clean flag."); > var canvas1 = document.getElementById("canvas1"); >- var gl1 = create3DContext(canvas1); >- assertMsg(!causedException(makeReadPixels(gl1)), >- "should not throw exception by readPixels for origin clean canvas."); >- assertMsg(!causedException(makeToDataURL(canvas1)), >- "should not throw exception by toDataURL for origin clean canvas."); >- >- var tex = gl1.createTexture(); >- gl1.bindTexture(gl1.TEXTURE_2D, tex); >- gl1.texImage2D(gl1.TEXTURE_2D, 0, gl1.RGBA, gl1.RGBA, gl1.UNSIGNED_BYTE, img); >- >- assertMsg(causedException(makeReadPixels(gl1)), >- "should throw exception by readPixels for NON origin clean canvas."); >- assertMsg(causedException(makeToDataURL(canvas1)), >- "should throw exception by toDataURL for NON origin clean canvas."); >+ var gl = create3DContext(canvas1); > > debug(""); >- debug("check that copying from 1 unclean 3d canvas to another clears the origin-clean flag on the second canvas."); >- var canvas2 = document.getElementById("canvas2"); >- var gl2 = create3DContext(canvas2); >- >- assertMsg(!causedException(makeReadPixels(gl2)), >- "should not throw exception by readPixels for origin clean canvas."); >- assertMsg(!causedException(makeToDataURL(canvas2)), >- "should not throw exception by toDataURL for origin clean canvas."); >- >- var tex = gl2.createTexture(); >- gl2.bindTexture(gl2.TEXTURE_2D, tex); >- gl2.texImage2D( >- gl2.TEXTURE_2D, 0, gl2.RGBA, gl2.RGBA, gl2.UNSIGNED_BYTE, canvas1); >+ 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."); > >- assertMsg(causedException(makeReadPixels(gl2)), >- "should throw exception by readPixels for NON origin clean canvas."); >+ 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."); > >- debug(""); >- debug("check that copying from 1 unclean 3d canvas to a 2d canvas clears the origin-clean flag on the 2d canvas."); >- var canvas3 = document.getElementById("canvas3"); >- var ctx2d = canvas3.getContext("2d"); >- assertMsg(!causedException(makeToDataURL(canvas3)), >- "should not throw exception by toDataURL for origin clean canvas."); >- ctx2d.drawImage(canvas2, 0, 0); >- assertMsg(causedException(makeToDataURL(canvas3)), >- "should throw exception by toDataURL for NON origin clean canvas."); >- >- debug(""); >- debug("check that copying a video from another origin clears the origin-clean flag."); >- var canvas4 = document.getElementById("canvas4"); >- var gl4 = create3DContext(canvas4); >- assertMsg(!causedException(makeReadPixels(gl4)), >- "should not throw exception by readPixels for origin clean canvas."); >- assertMsg(!causedException(makeToDataURL(canvas4)), >- "should not throw exception by toDataURL for origin clean canvas."); >- var tex4 = gl4.createTexture(); >- gl4.bindTexture(gl4.TEXTURE_2D, tex4); >- gl4.texImage2D( >- gl4.TEXTURE_2D, 0, gl4.RGBA, gl4.RGBA, gl4.UNSIGNED_BYTE, video); >- assertMsg(causedException(makeReadPixels(gl4)), >- "should throw exception by readPixels for NON origin clean canvas."); >- assertMsg(causedException(makeToDataURL(canvas4)), >- "should throw exception by toDataURL for NON origin clean canvas."); >+ 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) >@@ -211,8 +212,6 @@ function runTests() { > <div id="console"></div> > <canvas id="canvas1"></canvas> > <canvas id="canvas2"></canvas> >-<canvas id="canvas3"></canvas> >-<canvas id="canvas4"></canvas> > <img id="img" src="http://localhost:8000/local/resources/abe.png" style="display:none;"> > <video id="video" style="display:none;"/> > </body> >Index: LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt >=================================================================== >--- LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt (revision 0) >+++ LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt (revision 0) >@@ -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. >+ >Index: LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt >=================================================================== >--- LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt (revision 0) >+++ LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt (revision 0) >@@ -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. >+ >Index: LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html >=================================================================== >--- LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html (revision 0) >+++ LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html (revision 0) >@@ -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> >Index: LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed.html >=================================================================== >--- LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed.html (revision 0) >+++ LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed.html (revision 0) >@@ -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> >Index: LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt >=================================================================== >--- LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt (revision 0) >+++ LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt (revision 0) >@@ -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. >+ >Index: LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html >=================================================================== >--- LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html (revision 0) >+++ LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html (revision 0) >@@ -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> >Index: LayoutTests/platform/mac-wk2/Skipped >=================================================================== >--- LayoutTests/platform/mac-wk2/Skipped (revision 88316) >+++ LayoutTests/platform/mac-wk2/Skipped (working copy) >@@ -984,6 +984,9 @@ http/tests/inspector/network/ping.html > http/tests/navigation/ping-cross-origin-from-https.html > http/tests/navigation/ping-cross-origin.html > http/tests/navigation/ping-same-origin.html >+http/tests/security/webgl-remote-read-remote-image-allowed.html >+http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html >+http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html > loader/go-back-to-different-window-size.html > media/restore-from-page-cache.html > java/embedding-java-with-object.html
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
abarth
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 62257
: 96360