<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[195614] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/195614">195614</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-01-26 13:19:12 -0800 (Tue, 26 Jan 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Let SVG images not taint canvases except when containing foreignObjects
https://bugs.webkit.org/show_bug.cgi?id=119639

Patch by Philip Rogers &lt;pdr@chromium.org&gt; on 2016-01-26
Reviewed by Brent Fulgham.

Source/WebCore:

<a href="http://trac.webkit.org/projects/webkit/changeset/153876">r153876</a> caused SVG images to not taint canvases but the patch allowed
for subimage resources. This can be a problem if a subimage (e.g., data
uri image) contains a foreignObject which can violate security (e.g.,
visited links).

This patch updates SVGImage::hasSingleSecurityOrigin to check if the
image contains any foreignObjects or images that themselves contain
foreignObjects. SVG images without foreignObjects are allowed to not
taint canvases.

Canvas patterns are problematic because an animated SVG image can switch
between tainting and not tainting the canvas. A FIXME has been added to
solve this, and in the meantime we cause SVG images to taint patterns.

Tests: svg/as-image/svg-canvas-pattern-with-link-tainted.html
       svg/as-image/svg-canvas-svg-with-feimage-with-link-tainted.html
       svg/as-image/svg-canvas-svg-with-image-with-link-tainted.html

* html/canvas/CanvasPattern.cpp:
(WebCore::CanvasPattern::CanvasPattern):
(WebCore::CanvasPattern::~CanvasPattern):
* svg/SVGFEImageElement.cpp:
(WebCore::SVGFEImageElement::~SVGFEImageElement):
(WebCore::SVGFEImageElement::hasSingleSecurityOrigin):
(WebCore::SVGFEImageElement::clearResourceReferences):
* svg/SVGFEImageElement.h:
* svg/SVGImageElement.cpp:
(WebCore::SVGImageElement::create):
(WebCore::SVGImageElement::hasSingleSecurityOrigin):
(WebCore::SVGImageElement::isSupportedAttribute):
* svg/SVGImageElement.h:
* svg/graphics/SVGImage.cpp:
(WebCore::SVGImage::hasSingleSecurityOrigin):

LayoutTests:

* svg/as-image/resources/svg-with-feimage-with-link.svg: Added.
* svg/as-image/resources/svg-with-image-with-link.svg: Added.
* svg/as-image/svg-canvas-pattern-with-link-tainted-expected.txt: Added.
* svg/as-image/svg-canvas-pattern-with-link-tainted.html: Added.
* svg/as-image/svg-canvas-svg-with-feimage-with-link-tainted-expected.txt: Added.
* svg/as-image/svg-canvas-svg-with-feimage-with-link-tainted.html: Added.
* svg/as-image/svg-canvas-svg-with-image-with-link-tainted-expected.txt: Added.
* svg/as-image/svg-canvas-svg-with-image-with-link-tainted.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasCanvasRenderingContext2Dcpp">trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp</a></li>
<li><a href="#trunkSourceWebCoresvgSVGFEImageElementcpp">trunk/Source/WebCore/svg/SVGFEImageElement.cpp</a></li>
<li><a href="#trunkSourceWebCoresvgSVGFEImageElementh">trunk/Source/WebCore/svg/SVGFEImageElement.h</a></li>
<li><a href="#trunkSourceWebCoresvgSVGImageElementcpp">trunk/Source/WebCore/svg/SVGImageElement.cpp</a></li>
<li><a href="#trunkSourceWebCoresvgSVGImageElementh">trunk/Source/WebCore/svg/SVGImageElement.h</a></li>
<li><a href="#trunkSourceWebCoresvggraphicsSVGImagecpp">trunk/Source/WebCore/svg/graphics/SVGImage.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestssvgasimageresourcessvgwithfeimagewithlinksvg">trunk/LayoutTests/svg/as-image/resources/svg-with-feimage-with-link.svg</a></li>
<li><a href="#trunkLayoutTestssvgasimageresourcessvgwithimagewithlinksvg">trunk/LayoutTests/svg/as-image/resources/svg-with-image-with-link.svg</a></li>
<li><a href="#trunkLayoutTestssvgasimagesvgcanvaspatternwithlinktaintedexpectedtxt">trunk/LayoutTests/svg/as-image/svg-canvas-pattern-with-link-tainted-expected.txt</a></li>
<li><a href="#trunkLayoutTestssvgasimagesvgcanvaspatternwithlinktaintedhtml">trunk/LayoutTests/svg/as-image/svg-canvas-pattern-with-link-tainted.html</a></li>
<li><a href="#trunkLayoutTestssvgasimagesvgcanvassvgwithfeimagewithlinktaintedexpectedtxt">trunk/LayoutTests/svg/as-image/svg-canvas-svg-with-feimage-with-link-tainted-expected.txt</a></li>
<li><a href="#trunkLayoutTestssvgasimagesvgcanvassvgwithfeimagewithlinktaintedhtml">trunk/LayoutTests/svg/as-image/svg-canvas-svg-with-feimage-with-link-tainted.html</a></li>
<li><a href="#trunkLayoutTestssvgasimagesvgcanvassvgwithimagewithlinktaintedexpectedtxt">trunk/LayoutTests/svg/as-image/svg-canvas-svg-with-image-with-link-tainted-expected.txt</a></li>
<li><a href="#trunkLayoutTestssvgasimagesvgcanvassvgwithimagewithlinktaintedhtml">trunk/LayoutTests/svg/as-image/svg-canvas-svg-with-image-with-link-tainted.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (195613 => 195614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-01-26 21:14:33 UTC (rev 195613)
+++ trunk/LayoutTests/ChangeLog        2016-01-26 21:19:12 UTC (rev 195614)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2016-01-26  Philip Rogers  &lt;pdr@chromium.org&gt;
+
+        Let SVG images not taint canvases except when containing foreignObjects
+        https://bugs.webkit.org/show_bug.cgi?id=119639
+
+        Reviewed by Brent Fulgham.
+
+        * svg/as-image/resources/svg-with-feimage-with-link.svg: Added.
+        * svg/as-image/resources/svg-with-image-with-link.svg: Added.
+        * svg/as-image/svg-canvas-pattern-with-link-tainted-expected.txt: Added.
+        * svg/as-image/svg-canvas-pattern-with-link-tainted.html: Added.
+        * svg/as-image/svg-canvas-svg-with-feimage-with-link-tainted-expected.txt: Added.
+        * svg/as-image/svg-canvas-svg-with-feimage-with-link-tainted.html: Added.
+        * svg/as-image/svg-canvas-svg-with-image-with-link-tainted-expected.txt: Added.
+        * svg/as-image/svg-canvas-svg-with-image-with-link-tainted.html: Added.
+
</ins><span class="cx"> 2016-01-26  Jer Noble  &lt;jer.noble@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Calling video.controls=true during a scrub operation cancels scrub.
</span></span></pre></div>
<a id="trunkLayoutTestssvgasimageresourcessvgwithfeimagewithlinksvg"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/svg/as-image/resources/svg-with-feimage-with-link.svg (0 => 195614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/svg/as-image/resources/svg-with-feimage-with-link.svg                                (rev 0)
+++ trunk/LayoutTests/svg/as-image/resources/svg-with-feimage-with-link.svg        2016-01-26 21:19:12 UTC (rev 195614)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; viewBox=&quot;0 0 100 100&quot;&gt;
+    &lt;defs&gt;
+        &lt;filter id=&quot;filter&quot;&gt;
+            &lt;!-- This data uri image contains a foreignObject and a link. --&gt;
+            &lt;feImage xlink:href=&quot;data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMC8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1JFQy1TVkctMjAwMTA5MDQvRFREL3N2ZzEwLmR0ZCI+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGh0bWw9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj4NCiAgICA8YT48dGV4dD5saW5rPC90ZXh0PjwvYT4NCiAgICA8Zm9yZWlnbk9iamVjdCB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCI+DQogICAgICAgIDxzdHlsZT5hIGRpdiB7IGJhY2tncm91bmQtY29sb3I6IGdyZWVuOyB3aWR0aDogMTAwcHg7IGhlaWdodDogMTAwcHggfSBhOmxpbmsgZGl2LCBhOnZpc2l0ZWQgZGl2IHsgYmFja2dyb3VuZC1jb2xvcjogcmVkIH08L3N0eWxlPg0KICAgICAgICA8eGh0bWw6YSBocmVmPSJodHRwOi8vd3d3LmV4YW1wbGUuY29tLyI+PHhodG1sOmRpdj48L3hodG1sOmRpdj48L3hodG1sOmE+DQogICAgPC9mb3JlaWduT2JqZWN0Pg0KPC9zdmc+&quot; /&gt;
+        &lt;/filter&gt;
+    &lt;/defs&gt;
+    &lt;rect width=&quot;10&quot; height=&quot;10&quot; filter=&quot;url(#filter)&quot;/&gt;
+&lt;/svg&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestssvgasimageresourcessvgwithimagewithlinksvg"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/svg/as-image/resources/svg-with-image-with-link.svg (0 => 195614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/svg/as-image/resources/svg-with-image-with-link.svg                                (rev 0)
+++ trunk/LayoutTests/svg/as-image/resources/svg-with-image-with-link.svg        2016-01-26 21:19:12 UTC (rev 195614)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; viewBox=&quot;0 0 100 100&quot;&gt;
+    &lt;!-- This data uri image contains a foreignObject and a link. --&gt;
+    &lt;image width=&quot;10&quot; height=&quot;10&quot; xlink:href=&quot;data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMC8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1JFQy1TVkctMjAwMTA5MDQvRFREL3N2ZzEwLmR0ZCI+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGh0bWw9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj4NCiAgICA8YT48dGV4dD5saW5rPC90ZXh0PjwvYT4NCiAgICA8Zm9yZWlnbk9iamVjdCB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCI+DQogICAgICAgIDxzdHlsZT5hIGRpdiB7IGJhY2tncm91bmQtY29sb3I6IGdyZWVuOyB3aWR0aDogMTAwcHg7IGhlaWdodDogMTAwcHggfSBhOmxpbmsgZGl2LCBhOnZpc2l0ZWQgZGl2IHsgYmFja2dyb3VuZC1jb2xvcjogcmVkIH08L3N0eWxlPg0KICAgICAgICA8eGh0bWw6YSBocmVmPSJodHRwOi8vd3d3LmV4YW1wbGUuY29tLyI+PHhodG1sOmRpdj48L3hodG1sOmRpdj48L3hodG1sOmE+DQogICAgPC9mb3JlaWduT2JqZWN0Pg0KPC9zdmc+&quot;&gt;
+    &lt;/image&gt;
+&lt;/svg&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestssvgasimagesvgcanvaspatternwithlinktaintedexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/svg/as-image/svg-canvas-pattern-with-link-tainted-expected.txt (0 => 195614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/svg/as-image/svg-canvas-pattern-with-link-tainted-expected.txt                                (rev 0)
+++ trunk/LayoutTests/svg/as-image/svg-canvas-pattern-with-link-tainted-expected.txt        2016-01-26 21:19:12 UTC (rev 195614)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+CONSOLE MESSAGE: line 1: Unable to get image data from canvas because the canvas has been tainted by cross-origin data.
+PASS window.ctx.getImageData(0, 0, 1, 1) threw exception Error: SecurityError: DOM Exception 18.
+
</ins></span></pre></div>
<a id="trunkLayoutTestssvgasimagesvgcanvaspatternwithlinktaintedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/svg/as-image/svg-canvas-pattern-with-link-tainted.html (0 => 195614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/svg/as-image/svg-canvas-pattern-with-link-tainted.html                                (rev 0)
+++ trunk/LayoutTests/svg/as-image/svg-canvas-pattern-with-link-tainted.html        2016-01-26 21:19:12 UTC (rev 195614)
</span><span class="lines">@@ -0,0 +1,35 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+    &lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;script&gt;
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        var svg = new Image();
+        svg.src = &quot;resources/svg-with-feimage-with-link.svg&quot;;
+
+        svg.onload = function() {
+            var canvas = document.createElement(&quot;canvas&quot;);
+            window.ctx = canvas.getContext(&quot;2d&quot;);
+
+            ctx.getImageData(0, 0, 1, 1);
+
+            // Wait for the data uri in the image to load.
+            setTimeout(function() {
+                ctx.fillStyle = ctx.createPattern(svg, 'repeat');
+                ctx.fillRect(0, 0, 200, 200);
+
+                shouldThrow(&quot;window.ctx.getImageData(0, 0, 1, 1)&quot;);
+
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 50);
+        };
+    &lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestssvgasimagesvgcanvassvgwithfeimagewithlinktaintedexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/svg/as-image/svg-canvas-svg-with-feimage-with-link-tainted-expected.txt (0 => 195614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/svg/as-image/svg-canvas-svg-with-feimage-with-link-tainted-expected.txt                                (rev 0)
+++ trunk/LayoutTests/svg/as-image/svg-canvas-svg-with-feimage-with-link-tainted-expected.txt        2016-01-26 21:19:12 UTC (rev 195614)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+CONSOLE MESSAGE: line 1: Unable to get image data from canvas because the canvas has been tainted by cross-origin data.
+PASS window.ctx.getImageData(0, 0, 1, 1) threw exception Error: SecurityError: DOM Exception 18.
+
</ins></span></pre></div>
<a id="trunkLayoutTestssvgasimagesvgcanvassvgwithfeimagewithlinktaintedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/svg/as-image/svg-canvas-svg-with-feimage-with-link-tainted.html (0 => 195614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/svg/as-image/svg-canvas-svg-with-feimage-with-link-tainted.html                                (rev 0)
+++ trunk/LayoutTests/svg/as-image/svg-canvas-svg-with-feimage-with-link-tainted.html        2016-01-26 21:19:12 UTC (rev 195614)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+    &lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;script&gt;
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        var svg = new Image();
+        svg.src = &quot;resources/svg-with-feimage-with-link.svg&quot;;
+
+        svg.onload = function() {
+            var canvas = document.createElement(&quot;canvas&quot;);
+            window.ctx = canvas.getContext(&quot;2d&quot;);
+
+            ctx.getImageData(0, 0, 1, 1);
+
+            // Wait for the data uri in the image to load.
+            setTimeout(function() {
+                ctx.drawImage(svg, 0, 0);
+
+                shouldThrow(&quot;window.ctx.getImageData(0, 0, 1, 1)&quot;);
+
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 50);
+        };
+    &lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestssvgasimagesvgcanvassvgwithimagewithlinktaintedexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/svg/as-image/svg-canvas-svg-with-image-with-link-tainted-expected.txt (0 => 195614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/svg/as-image/svg-canvas-svg-with-image-with-link-tainted-expected.txt                                (rev 0)
+++ trunk/LayoutTests/svg/as-image/svg-canvas-svg-with-image-with-link-tainted-expected.txt        2016-01-26 21:19:12 UTC (rev 195614)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+CONSOLE MESSAGE: line 1: Unable to get image data from canvas because the canvas has been tainted by cross-origin data.
+PASS window.ctx.getImageData(0, 0, 1, 1) threw exception Error: SecurityError: DOM Exception 18.
+
</ins></span></pre></div>
<a id="trunkLayoutTestssvgasimagesvgcanvassvgwithimagewithlinktaintedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/svg/as-image/svg-canvas-svg-with-image-with-link-tainted.html (0 => 195614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/svg/as-image/svg-canvas-svg-with-image-with-link-tainted.html                                (rev 0)
+++ trunk/LayoutTests/svg/as-image/svg-canvas-svg-with-image-with-link-tainted.html        2016-01-26 21:19:12 UTC (rev 195614)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+    &lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;script&gt;
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        var svg = new Image();
+        svg.src = &quot;resources/svg-with-image-with-link.svg&quot;;
+
+        svg.onload = function() {
+            var canvas = document.createElement(&quot;canvas&quot;);
+            window.ctx = canvas.getContext(&quot;2d&quot;);
+
+            ctx.getImageData(0, 0, 1, 1);
+
+            // Wait for the data uri in the image to load.
+            setTimeout(function() {
+                ctx.drawImage(svg, 0, 0);
+
+                shouldThrow(&quot;window.ctx.getImageData(0, 0, 1, 1)&quot;);
+
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 50);
+        };
+    &lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (195613 => 195614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-01-26 21:14:33 UTC (rev 195613)
+++ trunk/Source/WebCore/ChangeLog        2016-01-26 21:19:12 UTC (rev 195614)
</span><span class="lines">@@ -1,3 +1,44 @@
</span><ins>+2016-01-26  Philip Rogers  &lt;pdr@chromium.org&gt;
+
+        Let SVG images not taint canvases except when containing foreignObjects
+        https://bugs.webkit.org/show_bug.cgi?id=119639
+
+        Reviewed by Brent Fulgham.
+
+        r153876 caused SVG images to not taint canvases but the patch allowed
+        for subimage resources. This can be a problem if a subimage (e.g., data
+        uri image) contains a foreignObject which can violate security (e.g.,
+        visited links).
+
+        This patch updates SVGImage::hasSingleSecurityOrigin to check if the
+        image contains any foreignObjects or images that themselves contain
+        foreignObjects. SVG images without foreignObjects are allowed to not
+        taint canvases.
+
+        Canvas patterns are problematic because an animated SVG image can switch
+        between tainting and not tainting the canvas. A FIXME has been added to
+        solve this, and in the meantime we cause SVG images to taint patterns.
+
+        Tests: svg/as-image/svg-canvas-pattern-with-link-tainted.html
+               svg/as-image/svg-canvas-svg-with-feimage-with-link-tainted.html
+               svg/as-image/svg-canvas-svg-with-image-with-link-tainted.html
+
+        * html/canvas/CanvasPattern.cpp:
+        (WebCore::CanvasPattern::CanvasPattern):
+        (WebCore::CanvasPattern::~CanvasPattern):
+        * svg/SVGFEImageElement.cpp:
+        (WebCore::SVGFEImageElement::~SVGFEImageElement):
+        (WebCore::SVGFEImageElement::hasSingleSecurityOrigin):
+        (WebCore::SVGFEImageElement::clearResourceReferences):
+        * svg/SVGFEImageElement.h:
+        * svg/SVGImageElement.cpp:
+        (WebCore::SVGImageElement::create):
+        (WebCore::SVGImageElement::hasSingleSecurityOrigin):
+        (WebCore::SVGImageElement::isSupportedAttribute):
+        * svg/SVGImageElement.h:
+        * svg/graphics/SVGImage.cpp:
+        (WebCore::SVGImage::hasSingleSecurityOrigin):
+
</ins><span class="cx"> 2016-01-26  Michael Catanzaro  &lt;mcatanzaro@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         CSSGrammar.y:1742.31-34: warning: unused value: $3
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasCanvasRenderingContext2Dcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp (195613 => 195614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp        2016-01-26 21:14:33 UTC (rev 195613)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp        2016-01-26 21:19:12 UTC (rev 195614)
</span><span class="lines">@@ -1825,6 +1825,16 @@
</span><span class="cx">         return CanvasPattern::create(Image::nullImage(), repeatX, repeatY, true);
</span><span class="cx"> 
</span><span class="cx">     bool originClean = cachedImage-&gt;isOriginClean(canvas()-&gt;securityOrigin());
</span><ins>+
+    // FIXME: SVG images with animations can switch between clean and dirty (leaking cross-origin
+    // data). We should either:
+    //   1) Take a fixed snapshot of an SVG image when creating a pattern and determine then whether
+    //      the origin is clean.
+    //   2) Dynamically verify the origin checks at draw time, and dirty the canvas accordingly.
+    // To be on the safe side, taint the origin for all patterns containing SVG images for now.
+    if (cachedImage-&gt;image()-&gt;isSVGImage())
+        originClean = false;
+
</ins><span class="cx">     return CanvasPattern::create(cachedImage-&gt;imageForRenderer(imageElement-&gt;renderer()), repeatX, repeatY, originClean);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoresvgSVGFEImageElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/SVGFEImageElement.cpp (195613 => 195614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/SVGFEImageElement.cpp        2016-01-26 21:14:33 UTC (rev 195613)
+++ trunk/Source/WebCore/svg/SVGFEImageElement.cpp        2016-01-26 21:19:12 UTC (rev 195614)
</span><span class="lines">@@ -65,6 +65,14 @@
</span><span class="cx">     clearResourceReferences();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool SVGFEImageElement::hasSingleSecurityOrigin() const
+{
+    if (!m_cachedImage)
+        return true;
+    auto* image = m_cachedImage-&gt;image();
+    return !image || image-&gt;hasSingleSecurityOrigin();
+}
+
</ins><span class="cx"> void SVGFEImageElement::clearResourceReferences()
</span><span class="cx"> {
</span><span class="cx">     if (m_cachedImage) {
</span></span></pre></div>
<a id="trunkSourceWebCoresvgSVGFEImageElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/SVGFEImageElement.h (195613 => 195614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/SVGFEImageElement.h        2016-01-26 21:14:33 UTC (rev 195613)
+++ trunk/Source/WebCore/svg/SVGFEImageElement.h        2016-01-26 21:19:12 UTC (rev 195614)
</span><span class="lines">@@ -42,6 +42,8 @@
</span><span class="cx"> 
</span><span class="cx">     virtual ~SVGFEImageElement();
</span><span class="cx"> 
</span><ins>+    bool hasSingleSecurityOrigin() const;
+
</ins><span class="cx"> private:
</span><span class="cx">     SVGFEImageElement(const QualifiedName&amp;, Document&amp;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoresvgSVGImageElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/SVGImageElement.cpp (195613 => 195614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/SVGImageElement.cpp        2016-01-26 21:14:33 UTC (rev 195613)
+++ trunk/Source/WebCore/svg/SVGImageElement.cpp        2016-01-26 21:19:12 UTC (rev 195614)
</span><span class="lines">@@ -69,6 +69,15 @@
</span><span class="cx">     return adoptRef(*new SVGImageElement(tagName, document));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool SVGImageElement::hasSingleSecurityOrigin() const
+{
+    auto* renderer = downcast&lt;RenderSVGImage&gt;(this-&gt;renderer());
+    if (!renderer || !renderer-&gt;imageResource().hasImage())
+        return true;
+    auto* image = renderer-&gt;imageResource().cachedImage()-&gt;image();
+    return !image || image-&gt;hasSingleSecurityOrigin();
+}
+
</ins><span class="cx"> bool SVGImageElement::isSupportedAttribute(const QualifiedName&amp; attrName)
</span><span class="cx"> {
</span><span class="cx">     static NeverDestroyed&lt;HashSet&lt;QualifiedName&gt;&gt; supportedAttributes;
</span></span></pre></div>
<a id="trunkSourceWebCoresvgSVGImageElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/SVGImageElement.h (195613 => 195614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/SVGImageElement.h        2016-01-26 21:14:33 UTC (rev 195613)
+++ trunk/Source/WebCore/svg/SVGImageElement.h        2016-01-26 21:19:12 UTC (rev 195614)
</span><span class="lines">@@ -37,6 +37,8 @@
</span><span class="cx"> public:
</span><span class="cx">     static Ref&lt;SVGImageElement&gt; create(const QualifiedName&amp;, Document&amp;);
</span><span class="cx"> 
</span><ins>+    bool hasSingleSecurityOrigin() const;
+
</ins><span class="cx"> private:
</span><span class="cx">     SVGImageElement(const QualifiedName&amp;, Document&amp;);
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceWebCoresvggraphicsSVGImagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/graphics/SVGImage.cpp (195613 => 195614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/graphics/SVGImage.cpp        2016-01-26 21:14:33 UTC (rev 195613)
+++ trunk/Source/WebCore/svg/graphics/SVGImage.cpp        2016-01-26 21:19:12 UTC (rev 195614)
</span><span class="lines">@@ -41,8 +41,10 @@
</span><span class="cx"> #include &quot;RenderSVGRoot.h&quot;
</span><span class="cx"> #include &quot;RenderStyle.h&quot;
</span><span class="cx"> #include &quot;SVGDocument.h&quot;
</span><ins>+#include &quot;SVGFEImageElement.h&quot;
</ins><span class="cx"> #include &quot;SVGForeignObjectElement.h&quot;
</span><span class="cx"> #include &quot;SVGImageClients.h&quot;
</span><ins>+#include &quot;SVGImageElement.h&quot;
</ins><span class="cx"> #include &quot;SVGSVGElement.h&quot;
</span><span class="cx"> #include &quot;Settings.h&quot;
</span><span class="cx"> #include &quot;TextStream.h&quot;
</span><span class="lines">@@ -80,9 +82,20 @@
</span><span class="cx">     if (!rootElement)
</span><span class="cx">         return true;
</span><span class="cx"> 
</span><del>-    // Don't allow foreignObject elements since they can leak information with arbitrary HTML (like spellcheck or control theme).
-    if (descendantsOfType&lt;SVGForeignObjectElement&gt;(*rootElement).first())
-        return false;
</del><ins>+    // FIXME: Once foreignObject elements within SVG images are updated to not leak cross-origin data
+    // (e.g., visited links, spellcheck) we can remove the SVGForeignObjectElement check here and
+    // research if we can remove the Image::hasSingleSecurityOrigin mechanism entirely.
+    for (auto&amp; element : descendantsOfType&lt;SVGElement&gt;(*rootElement)) {
+        if (is&lt;SVGForeignObjectElement&gt;(element))
+            return false;
+        if (is&lt;SVGImageElement&gt;(element)) {
+            if (!downcast&lt;SVGImageElement&gt;(element).hasSingleSecurityOrigin())
+                return false;
+        } else if (is&lt;SVGFEImageElement&gt;(element)) {
+            if (!downcast&lt;SVGFEImageElement&gt;(element).hasSingleSecurityOrigin())
+                return false;
+        }
+    }
</ins><span class="cx"> 
</span><span class="cx">     // Because SVG image rendering disallows external resources and links,
</span><span class="cx">     // these images effectively are restricted to a single security origin.
</span></span></pre>
</div>
</div>

</body>
</html>