<!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>[183576] 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/183576">183576</a></dd>
<dt>Author</dt> <dd>zalan@apple.com</dd>
<dt>Date</dt> <dd>2015-04-29 14:32:07 -0700 (Wed, 29 Apr 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Simple line layout: Web process spins endlessly below layoutSimpleLines.
https://bugs.webkit.org/show_bug.cgi?id=144403
rdar://problem/20742783

Reviewed by Antti Koivisto.

When a text fragment overlaps multiple renderes and it does not fit the current line,
we revert the text fragment iterator position so that the overlapping content
gets processed again for the next line.
However, TextFragmentIterator::revertToFragment() was reverting too much and
we started processing old content all over again -&gt; infinite loop.

This patch ensures that text fragment iterator is reverted to the right position.

Source/WebCore:

Test: fast/text/simple-line-layout-wrapping-multiple-renderers-hang.html

* rendering/SimpleLineLayout.cpp:
(WebCore::SimpleLineLayout::createLineRuns):
* rendering/SimpleLineLayoutTextFragmentIterator.cpp:
(WebCore::SimpleLineLayout::TextFragmentIterator::revertToEndOfFragment):
(WebCore::SimpleLineLayout::TextFragmentIterator::revertToFragment): Deleted.
* rendering/SimpleLineLayoutTextFragmentIterator.h:

LayoutTests:

* fast/text/simple-line-layout-wrapping-multiple-renderers-hang-expected.html: Added.
* fast/text/simple-line-layout-wrapping-multiple-renderers-hang.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="#trunkSourceWebCorerenderingSimpleLineLayoutcpp">trunk/Source/WebCore/rendering/SimpleLineLayout.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingSimpleLineLayoutTextFragmentIteratorcpp">trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingSimpleLineLayoutTextFragmentIteratorh">trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfasttextsimplelinelayoutwrappingmultiplerenderershangexpectedhtml">trunk/LayoutTests/fast/text/simple-line-layout-wrapping-multiple-renderers-hang-expected.html</a></li>
<li><a href="#trunkLayoutTestsfasttextsimplelinelayoutwrappingmultiplerenderershanghtml">trunk/LayoutTests/fast/text/simple-line-layout-wrapping-multiple-renderers-hang.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (183575 => 183576)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-04-29 21:27:48 UTC (rev 183575)
+++ trunk/LayoutTests/ChangeLog        2015-04-29 21:32:07 UTC (rev 183576)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2015-04-29  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        Simple line layout: Web process spins endlessly below layoutSimpleLines.
+        https://bugs.webkit.org/show_bug.cgi?id=144403
+        rdar://problem/20742783
+
+        Reviewed by Antti Koivisto.
+
+        When a text fragment overlaps multiple renderes and it does not fit the current line,
+        we revert the text fragment iterator position so that the overlapping content
+        gets processed again for the next line.
+        However, TextFragmentIterator::revertToFragment() was reverting too much and
+        we started processing old content all over again -&gt; infinite loop.
+
+        This patch ensures that text fragment iterator is reverted to the right position.
+
+        * fast/text/simple-line-layout-wrapping-multiple-renderers-hang-expected.html: Added.
+        * fast/text/simple-line-layout-wrapping-multiple-renderers-hang.html: Added.
+
</ins><span class="cx"> 2015-04-29  Antti Koivisto  &lt;antti@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Mark newly added http/tests/cache/main-resource-304-reload.html failing on Windows.
</span></span></pre></div>
<a id="trunkLayoutTestsfasttextsimplelinelayoutwrappingmultiplerenderershangexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/text/simple-line-layout-wrapping-multiple-renderers-hang-expected.html (0 => 183576)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/text/simple-line-layout-wrapping-multiple-renderers-hang-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/text/simple-line-layout-wrapping-multiple-renderers-hang-expected.html        2015-04-29 21:32:07 UTC (rev 183576)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;This tests that simple line layout manages text fragments when they overlap multiple renderers.&lt;/title&gt;
+&lt;style&gt;
+pre {
+    width: 45px; 
+    word-wrap: break-word;
+    white-space: pre-wrap;
+}
+&lt;/style&gt;
+&lt;script&gt;
+    if (window.internals)
+        internals.settings.setSimpleLineLayoutEnabled(false);
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+The test passes if it does not hang or crash.
+&lt;pre id=container&gt;&lt;/pre&gt;
+&lt;script&gt;
+    var container = document.getElementById(&quot;container&quot;);
+    container.appendChild(document.createTextNode(&quot;A foo&quot;));                        
+    container.appendChild(document.createTextNode(&quot;bar foobar&quot;));                        
+    document.body.offsetWidth;                        
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfasttextsimplelinelayoutwrappingmultiplerenderershanghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/text/simple-line-layout-wrapping-multiple-renderers-hang.html (0 => 183576)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/text/simple-line-layout-wrapping-multiple-renderers-hang.html                                (rev 0)
+++ trunk/LayoutTests/fast/text/simple-line-layout-wrapping-multiple-renderers-hang.html        2015-04-29 21:32:07 UTC (rev 183576)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;This tests that simple line layout manages text fragments when they overlap multiple renderers.&lt;/title&gt;
+&lt;style&gt;
+pre {
+    width: 45px; 
+    word-wrap: break-word;
+    white-space: pre-wrap;
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+The test passes if it does not hang or crash.
+&lt;pre id=container&gt;&lt;/pre&gt;
+&lt;script&gt;
+    var container = document.getElementById(&quot;container&quot;);
+    container.appendChild(document.createTextNode(&quot;A foo&quot;));                        
+    container.appendChild(document.createTextNode(&quot;bar foobar&quot;));                        
+    document.body.offsetWidth;                        
+&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 (183575 => 183576)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-04-29 21:27:48 UTC (rev 183575)
+++ trunk/Source/WebCore/ChangeLog        2015-04-29 21:32:07 UTC (rev 183576)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2015-04-29  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        Simple line layout: Web process spins endlessly below layoutSimpleLines.
+        https://bugs.webkit.org/show_bug.cgi?id=144403
+        rdar://problem/20742783
+
+        Reviewed by Antti Koivisto.
+
+        When a text fragment overlaps multiple renderes and it does not fit the current line,
+        we revert the text fragment iterator position so that the overlapping content
+        gets processed again for the next line.
+        However, TextFragmentIterator::revertToFragment() was reverting too much and
+        we started processing old content all over again -&gt; infinite loop.
+
+        This patch ensures that text fragment iterator is reverted to the right position.
+
+        Test: fast/text/simple-line-layout-wrapping-multiple-renderers-hang.html
+
+        * rendering/SimpleLineLayout.cpp:
+        (WebCore::SimpleLineLayout::createLineRuns):
+        * rendering/SimpleLineLayoutTextFragmentIterator.cpp:
+        (WebCore::SimpleLineLayout::TextFragmentIterator::revertToEndOfFragment):
+        (WebCore::SimpleLineLayout::TextFragmentIterator::revertToFragment): Deleted.
+        * rendering/SimpleLineLayoutTextFragmentIterator.h:
+
</ins><span class="cx"> 2015-04-29  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         JSTypeInfo should have an inline type flag to indicate of getCallData() has been overridden
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingSimpleLineLayoutcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/SimpleLineLayout.cpp (183575 => 183576)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/SimpleLineLayout.cpp        2015-04-29 21:27:48 UTC (rev 183575)
+++ trunk/Source/WebCore/rendering/SimpleLineLayout.cpp        2015-04-29 21:32:07 UTC (rev 183576)
</span><span class="lines">@@ -567,8 +567,8 @@
</span><span class="cx">             // Non-breakable non-whitespace fragment when there's already content on the line. Push it to the next line.
</span><span class="cx">             if (line.lastFragment().overlapsToNextRenderer()) {
</span><span class="cx">                 // Check if this fragment is a continuation of a previous segment. In such cases, we need to remove them all.
</span><del>-                const auto&amp; currentFragment = line.revertToLastCompleteFragment(runs);
-                textFragmentIterator.revertToFragment(currentFragment);
</del><ins>+                const auto&amp; lastCompleteFragment = line.revertToLastCompleteFragment(runs);
+                textFragmentIterator.revertToEndOfFragment(lastCompleteFragment);
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             line.setOverflowedFragment(fragment);
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingSimpleLineLayoutTextFragmentIteratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp (183575 => 183576)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp        2015-04-29 21:27:48 UTC (rev 183575)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp        2015-04-29 21:32:07 UTC (rev 183576)
</span><span class="lines">@@ -98,15 +98,14 @@
</span><span class="cx">     return TextFragment(startPosition, endPosition, width, TextFragment::NonWhitespace, endPosition == segmentEndPosition, overlappingFragment, false, false, m_style.breakWordOnOverflow);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void TextFragmentIterator::revertToFragment(const TextFragment&amp; fragment)
</del><ins>+void TextFragmentIterator::revertToEndOfFragment(const TextFragment&amp; fragment)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_position &gt;= fragment.end());
</span><del>-    // Revert segment first.
-    while (m_currentSegment-&gt;start &gt; fragment.start())
</del><ins>+    while (m_currentSegment-&gt;start &gt; fragment.end())
</ins><span class="cx">         --m_currentSegment;
</span><span class="cx">     // TODO: It reverts to the last fragment on the same position, but that's ok for now as we don't need to
</span><span class="cx">     // differentiate multiple renderers on the same position.
</span><del>-    m_position = fragment.start();
</del><ins>+    m_position = fragment.end();
</ins><span class="cx">     m_atEndOfSegment = false;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingSimpleLineLayoutTextFragmentIteratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h (183575 => 183576)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h        2015-04-29 21:27:48 UTC (rev 183575)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h        2015-04-29 21:32:07 UTC (rev 183576)
</span><span class="lines">@@ -95,7 +95,7 @@
</span><span class="cx">         bool m_isBreakable { false };
</span><span class="cx">     };
</span><span class="cx">     TextFragment nextTextFragment(float xPosition = 0);
</span><del>-    void revertToFragment(const TextFragment&amp;);
</del><ins>+    void revertToEndOfFragment(const TextFragment&amp;);
</ins><span class="cx">     float textWidth(unsigned startPosition, unsigned endPosition, float xPosition) const;
</span><span class="cx"> 
</span><span class="cx">     struct Style {
</span></span></pre>
</div>
</div>

</body>
</html>