<!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>[207848] 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/207848">207848</a></dd>
<dt>Author</dt> <dd>dbates@webkit.org</dd>
<dt>Date</dt> <dd>2016-10-25 15:07:20 -0700 (Tue, 25 Oct 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>REGRESSION (<a href="http://trac.webkit.org/projects/webkit/changeset/178265">r178265</a>): XSS Auditor fails to block document.write() of incomplete tag
https://bugs.webkit.org/show_bug.cgi?id=163978
&lt;rdar://problem/25962131&gt;

Reviewed by Darin Adler.

Source/WebCore:

During the tokenization process of an HTML tag the start and end positions of each of its
attributes is tracked so that the XSS Auditor can request a snippet around a suspected
injected attribute. We need to take care to consider document.write() boundaries when
tracking the start and end positions of each HTML tag and attribute so that the XSS Auditor
receives the correct snippet. Following <a href="http://trac.webkit.org/projects/webkit/changeset/178265">r178265</a> we no longer consider document.write()
boundaries when tracking the start and end positions of attributes. So, the substring
represented by the start and end positions of an attribute may correspond to some other
attribute in the tag. Therefore the XSS Auditor may fail to block an injection because the
snippet it requested may not be the snippet that it intended to request.

Tests: http/tests/security/xssAuditor/dom-write-location-dom-write-open-img-onerror.html
       http/tests/security/xssAuditor/dom-write-location-open-img-onerror.html
       http/tests/security/xssAuditor/nested-dom-write-location-open-img-onerror.html

* html/parser/HTMLSourceTracker.cpp:
(WebCore::HTMLSourceTracker::startToken): Set the attribute base offset to be the token
start position.
(WebCore::HTMLSourceTracker::source): Use the specified attribute start position as-is. We no
longer adjust it here because it was adjusted with respect to the attribute base offset, which
takes into account document.write() boundaries.
* html/parser/HTMLToken.h:
(WebCore::HTMLToken::setAttributeBaseOffset): Added.
(WebCore::HTMLToken::beginAttribute): Subtract attribute base offset from the specified offset.
(WebCore::HTMLToken::endAttribute): Ditto.
* html/parser/HTMLTokenizer.h:
(WebCore::HTMLTokenizer::setTokenAttributeBaseOffset): Added.

LayoutTests:

Add tests to ensure that the XSS Auditor blocks a document.write() of an incomplete HTML image tag.

* http/tests/security/xssAuditor/dom-write-location-dom-write-open-img-onerror-expected.txt: Added.
* http/tests/security/xssAuditor/dom-write-location-dom-write-open-img-onerror.html: Added.
* http/tests/security/xssAuditor/dom-write-location-open-img-onerror-expected.txt: Added.
* http/tests/security/xssAuditor/dom-write-location-open-img-onerror.html: Added.
* http/tests/security/xssAuditor/nested-dom-write-location-open-img-onerror-expected.txt: Added.
* http/tests/security/xssAuditor/nested-dom-write-location-open-img-onerror.html: Added.
* http/tests/security/xssAuditor/resources/echo-nested-dom-write-location.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="#trunkSourceWebCorehtmlparserHTMLSourceTrackercpp">trunk/Source/WebCore/html/parser/HTMLSourceTracker.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLTokenh">trunk/Source/WebCore/html/parser/HTMLToken.h</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLTokenizerh">trunk/Source/WebCore/html/parser/HTMLTokenizer.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestshttptestssecurityxssAuditordomwritelocationdomwriteopenimgonerrorexpectedtxt">trunk/LayoutTests/http/tests/security/xssAuditor/dom-write-location-dom-write-open-img-onerror-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestssecurityxssAuditordomwritelocationdomwriteopenimgonerrorhtml">trunk/LayoutTests/http/tests/security/xssAuditor/dom-write-location-dom-write-open-img-onerror.html</a></li>
<li><a href="#trunkLayoutTestshttptestssecurityxssAuditordomwritelocationopenimgonerrorexpectedtxt">trunk/LayoutTests/http/tests/security/xssAuditor/dom-write-location-open-img-onerror-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestssecurityxssAuditordomwritelocationopenimgonerrorhtml">trunk/LayoutTests/http/tests/security/xssAuditor/dom-write-location-open-img-onerror.html</a></li>
<li><a href="#trunkLayoutTestshttptestssecurityxssAuditornesteddomwritelocationopenimgonerrorexpectedtxt">trunk/LayoutTests/http/tests/security/xssAuditor/nested-dom-write-location-open-img-onerror-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestssecurityxssAuditornesteddomwritelocationopenimgonerrorhtml">trunk/LayoutTests/http/tests/security/xssAuditor/nested-dom-write-location-open-img-onerror.html</a></li>
<li><a href="#trunkLayoutTestshttptestssecurityxssAuditorresourcesechonesteddomwritelocationhtml">trunk/LayoutTests/http/tests/security/xssAuditor/resources/echo-nested-dom-write-location.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (207847 => 207848)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-10-25 22:01:55 UTC (rev 207847)
+++ trunk/LayoutTests/ChangeLog        2016-10-25 22:07:20 UTC (rev 207848)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2016-10-25  Daniel Bates  &lt;dabates@apple.com&gt;
+
+        REGRESSION (r178265): XSS Auditor fails to block document.write() of incomplete tag
+        https://bugs.webkit.org/show_bug.cgi?id=163978
+        &lt;rdar://problem/25962131&gt;
+
+        Reviewed by Darin Adler.
+
+        Add tests to ensure that the XSS Auditor blocks a document.write() of an incomplete HTML image tag.
+
+        * http/tests/security/xssAuditor/dom-write-location-dom-write-open-img-onerror-expected.txt: Added.
+        * http/tests/security/xssAuditor/dom-write-location-dom-write-open-img-onerror.html: Added.
+        * http/tests/security/xssAuditor/dom-write-location-open-img-onerror-expected.txt: Added.
+        * http/tests/security/xssAuditor/dom-write-location-open-img-onerror.html: Added.
+        * http/tests/security/xssAuditor/nested-dom-write-location-open-img-onerror-expected.txt: Added.
+        * http/tests/security/xssAuditor/nested-dom-write-location-open-img-onerror.html: Added.
+        * http/tests/security/xssAuditor/resources/echo-nested-dom-write-location.html: Added.
+
</ins><span class="cx"> 2016-10-25  Brady Eidson  &lt;beidson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         IndexedDB 2.0: Support IDBObjectStore openKeyCursor.
</span></span></pre></div>
<a id="trunkLayoutTestshttptestssecurityxssAuditordomwritelocationdomwriteopenimgonerrorexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/security/xssAuditor/dom-write-location-dom-write-open-img-onerror-expected.txt (0 => 207848)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/xssAuditor/dom-write-location-dom-write-open-img-onerror-expected.txt                                (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/dom-write-location-dom-write-open-img-onerror-expected.txt        2016-10-25 22:07:20 UTC (rev 207848)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+CONSOLE MESSAGE: line 6: The XSS Auditor refused to execute a script in 'http://localhost:8000/security/xssAuditor/resources/echo-dom-write-location.html?q=%3Cscript%3Edocument.write(%22%3Cimg%20src=1%20%22);%3C/script%3Eonerror=alert(/XSS/)' because its source code was found within the request. The auditor was enabled because the server did not send an 'X-XSS-Protection' header.
+
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestssecurityxssAuditordomwritelocationdomwriteopenimgonerrorhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/security/xssAuditor/dom-write-location-dom-write-open-img-onerror.html (0 => 207848)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/xssAuditor/dom-write-location-dom-write-open-img-onerror.html                                (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/dom-write-location-dom-write-open-img-onerror.html        2016-10-25 22:07:20 UTC (rev 207848)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script&gt;
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.setXSSAuditorEnabled(true);
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;iframe src='http://localhost:8000/security/xssAuditor/resources/echo-dom-write-location.html?q=&lt;script&gt;document.write(&quot;&lt;img src=1 &quot;);&lt;/script&gt;onerror=alert(/XSS/)'&gt;
+&lt;/iframe&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestssecurityxssAuditordomwritelocationopenimgonerrorexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/security/xssAuditor/dom-write-location-open-img-onerror-expected.txt (0 => 207848)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/xssAuditor/dom-write-location-open-img-onerror-expected.txt                                (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/dom-write-location-open-img-onerror-expected.txt        2016-10-25 22:07:20 UTC (rev 207848)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+CONSOLE MESSAGE: line 7: The XSS Auditor refused to execute a script in 'http://localhost:8000/security/xssAuditor/resources/echo-dom-write-location.html?q=%3Cimg%20src=1%20onerror=alert(/XSS/)' because its source code was found within the request. The auditor was enabled because the server did not send an 'X-XSS-Protection' header.
+
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestssecurityxssAuditordomwritelocationopenimgonerrorhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/security/xssAuditor/dom-write-location-open-img-onerror.html (0 => 207848)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/xssAuditor/dom-write-location-open-img-onerror.html                                (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/dom-write-location-open-img-onerror.html        2016-10-25 22:07:20 UTC (rev 207848)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script&gt;
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.setXSSAuditorEnabled(true);
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;iframe src='http://localhost:8000/security/xssAuditor/resources/echo-dom-write-location.html?q=&lt;img%20src=1%20onerror=alert(/XSS/)'&gt;
+&lt;/iframe&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestssecurityxssAuditornesteddomwritelocationopenimgonerrorexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/security/xssAuditor/nested-dom-write-location-open-img-onerror-expected.txt (0 => 207848)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/xssAuditor/nested-dom-write-location-open-img-onerror-expected.txt                                (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/nested-dom-write-location-open-img-onerror-expected.txt        2016-10-25 22:07:20 UTC (rev 207848)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+CONSOLE MESSAGE: line 7: The XSS Auditor refused to execute a script in 'http://localhost:8000/security/xssAuditor/resources/echo-nested-dom-write-location.html?q=%3Cimg%20src=1%20onerror=alert(/XSS/)' because its source code was found within the request. The auditor was enabled because the server did not send an 'X-XSS-Protection' header.
+
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestssecurityxssAuditornesteddomwritelocationopenimgonerrorhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/security/xssAuditor/nested-dom-write-location-open-img-onerror.html (0 => 207848)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/xssAuditor/nested-dom-write-location-open-img-onerror.html                                (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/nested-dom-write-location-open-img-onerror.html        2016-10-25 22:07:20 UTC (rev 207848)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script&gt;
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.setXSSAuditorEnabled(true);
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;iframe src='http://localhost:8000/security/xssAuditor/resources/echo-nested-dom-write-location.html?q=&lt;img%20src=1%20onerror=alert(/XSS/)'&gt;
+&lt;/iframe&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestssecurityxssAuditorresourcesechonesteddomwritelocationhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/security/xssAuditor/resources/echo-nested-dom-write-location.html (0 => 207848)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/xssAuditor/resources/echo-nested-dom-write-location.html                                (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/resources/echo-nested-dom-write-location.html        2016-10-25 22:07:20 UTC (rev 207848)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;document.write(&quot;&lt;script&gt;document.write(unescape(window.location));&lt;/&quot; + &quot;script&gt;&quot;);&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 (207847 => 207848)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-10-25 22:01:55 UTC (rev 207847)
+++ trunk/Source/WebCore/ChangeLog        2016-10-25 22:07:20 UTC (rev 207848)
</span><span class="lines">@@ -1,3 +1,38 @@
</span><ins>+2016-10-25  Daniel Bates  &lt;dabates@apple.com&gt;
+
+        REGRESSION (r178265): XSS Auditor fails to block document.write() of incomplete tag
+        https://bugs.webkit.org/show_bug.cgi?id=163978
+        &lt;rdar://problem/25962131&gt;
+
+        Reviewed by Darin Adler.
+
+        During the tokenization process of an HTML tag the start and end positions of each of its
+        attributes is tracked so that the XSS Auditor can request a snippet around a suspected
+        injected attribute. We need to take care to consider document.write() boundaries when
+        tracking the start and end positions of each HTML tag and attribute so that the XSS Auditor
+        receives the correct snippet. Following r178265 we no longer consider document.write()
+        boundaries when tracking the start and end positions of attributes. So, the substring
+        represented by the start and end positions of an attribute may correspond to some other
+        attribute in the tag. Therefore the XSS Auditor may fail to block an injection because the
+        snippet it requested may not be the snippet that it intended to request.
+
+        Tests: http/tests/security/xssAuditor/dom-write-location-dom-write-open-img-onerror.html
+               http/tests/security/xssAuditor/dom-write-location-open-img-onerror.html
+               http/tests/security/xssAuditor/nested-dom-write-location-open-img-onerror.html
+
+        * html/parser/HTMLSourceTracker.cpp:
+        (WebCore::HTMLSourceTracker::startToken): Set the attribute base offset to be the token
+        start position.
+        (WebCore::HTMLSourceTracker::source): Use the specified attribute start position as-is. We no
+        longer adjust it here because it was adjusted with respect to the attribute base offset, which
+        takes into account document.write() boundaries.
+        * html/parser/HTMLToken.h:
+        (WebCore::HTMLToken::setAttributeBaseOffset): Added.
+        (WebCore::HTMLToken::beginAttribute): Subtract attribute base offset from the specified offset.
+        (WebCore::HTMLToken::endAttribute): Ditto.
+        * html/parser/HTMLTokenizer.h:
+        (WebCore::HTMLTokenizer::setTokenAttributeBaseOffset): Added.
+
</ins><span class="cx"> 2016-10-25  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         IDBDatabase.transaction() should take a union in parameter
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLSourceTrackercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLSourceTracker.cpp (207847 => 207848)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLSourceTracker.cpp        2016-10-25 22:01:55 UTC (rev 207847)
+++ trunk/Source/WebCore/html/parser/HTMLSourceTracker.cpp        2016-10-25 22:07:20 UTC (rev 207848)
</span><span class="lines">@@ -49,6 +49,7 @@
</span><span class="cx"> 
</span><span class="cx">     m_currentSource = currentInput;
</span><span class="cx">     m_tokenStart = m_currentSource.numberOfCharactersConsumed() - m_previousSource.length();
</span><ins>+    tokenizer.setTokenAttributeBaseOffset(m_tokenStart);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTMLSourceTracker::endToken(SegmentedString&amp; currentInput, HTMLTokenizer&amp; tokenizer)
</span><span class="lines">@@ -92,7 +93,7 @@
</span><span class="cx"> 
</span><span class="cx"> String HTMLSourceTracker::source(const HTMLToken&amp; token, unsigned attributeStart, unsigned attributeEnd)
</span><span class="cx"> {
</span><del>-    return source(token).substring(attributeStart - m_tokenStart, attributeEnd - attributeStart);
</del><ins>+    return source(token).substring(attributeStart, attributeEnd - attributeStart);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLTokenh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLToken.h (207847 => 207848)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLToken.h        2016-10-25 22:01:55 UTC (rev 207847)
+++ trunk/Source/WebCore/html/parser/HTMLToken.h        2016-10-25 22:07:20 UTC (rev 207848)
</span><span class="lines">@@ -114,6 +114,9 @@
</span><span class="cx"> 
</span><span class="cx">     void setSelfClosing();
</span><span class="cx"> 
</span><ins>+    // Used by HTMLTokenizer on behalf of HTMLSourceTracker.
+    void setAttributeBaseOffset(unsigned attributeBaseOffset) { m_attributeBaseOffset = attributeBaseOffset; }
+
</ins><span class="cx"> public:
</span><span class="cx">     // Used by the XSSAuditor to nuke XSS-laden attributes.
</span><span class="cx">     void eraseValueOfAttribute(unsigned index);
</span><span class="lines">@@ -153,6 +156,8 @@
</span><span class="cx"> 
</span><span class="cx">     // For DOCTYPE
</span><span class="cx">     std::unique_ptr&lt;DoctypeData&gt; m_doctypeData;
</span><ins>+
+    unsigned m_attributeBaseOffset { 0 }; // Changes across document.write() boundaries.
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> const HTMLToken::Attribute* findAttribute(const Vector&lt;HTMLToken::Attribute&gt;&amp;, StringView name);
</span><span class="lines">@@ -315,7 +320,7 @@
</span><span class="cx">     m_attributes.grow(m_attributes.size() + 1);
</span><span class="cx">     m_currentAttribute = &amp;m_attributes.last();
</span><span class="cx"> 
</span><del>-    m_currentAttribute-&gt;startOffset = offset;
</del><ins>+    m_currentAttribute-&gt;startOffset = offset - m_attributeBaseOffset;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline void HTMLToken::endAttribute(unsigned offset)
</span><span class="lines">@@ -322,7 +327,7 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(offset);
</span><span class="cx">     ASSERT(m_currentAttribute);
</span><del>-    m_currentAttribute-&gt;endOffset = offset;
</del><ins>+    m_currentAttribute-&gt;endOffset = offset - m_attributeBaseOffset;
</ins><span class="cx"> #if !ASSERT_DISABLED
</span><span class="cx">     m_currentAttribute = nullptr;
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLTokenizerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLTokenizer.h (207847 => 207848)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLTokenizer.h        2016-10-25 22:01:55 UTC (rev 207847)
+++ trunk/Source/WebCore/html/parser/HTMLTokenizer.h        2016-10-25 22:07:20 UTC (rev 207848)
</span><span class="lines">@@ -43,6 +43,9 @@
</span><span class="cx">     class TokenPtr;
</span><span class="cx">     TokenPtr nextToken(SegmentedString&amp;);
</span><span class="cx"> 
</span><ins>+    // Used by HTMLSourceTracker.
+    void setTokenAttributeBaseOffset(unsigned);
+
</ins><span class="cx">     // Returns a copy of any characters buffered internally by the tokenizer.
</span><span class="cx">     // The tokenizer buffers characters when searching for the &lt;/script&gt; token that terminates a script element.
</span><span class="cx">     String bufferedCharacters() const;
</span><span class="lines">@@ -282,6 +285,11 @@
</span><span class="cx">     return TokenPtr(processToken(source) ? &amp;m_token : nullptr);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline void HTMLTokenizer::setTokenAttributeBaseOffset(unsigned offset)
+{
+    m_token.setAttributeBaseOffset(offset);
+}
+
</ins><span class="cx"> inline size_t HTMLTokenizer::numberOfBufferedCharacters() const
</span><span class="cx"> {
</span><span class="cx">     // Notice that we add 2 to the length of the m_temporaryBuffer to
</span></span></pre>
</div>
</div>

</body>
</html>