Crash in WebCore::InlineBox::deleteLine
https://bugs.webkit.org/show_bug.cgi?id=93448

Patch by Douglas Stockwell <dstockwell@chromium.org> on 2013-01-02
Reviewed by Eric Seidel.

Source/WebCore:

When we ran off the end of the line while looking for line breaks in an
inline with white-space:nowrap nested in a block with white-space:pre
it was possible for the line break to be set at or before the current
position -- this could result in duplications in the render tree or
infinite looping.

This patch changes the "fixup" logic that runs after we have finished
iterating through elements and text and have potentially found a break
point. In the case of a block setting white-space:pre we would back up
a character in some cases. Not doing so could leave whitespace that
should have been collapsed at the end of an inline.

For example in '<span style="white-space:nowrap">x_</span>_y' if a
break was inserted before 'y' the space after 'x' would still be
rendered (rather than be collapsed with the break).

To avoid this problem we will not take the opportunity to break until
we have finished collapsing whitespace.

Tests: fast/text/whitespace/inline-whitespace-wrapping-1.html
       fast/text/whitespace/inline-whitespace-wrapping-2.html
       fast/text/whitespace/inline-whitespace-wrapping-3.html
       fast/text/whitespace/inline-whitespace-wrapping-4.html
       fast/text/whitespace/nowrap-white-space-collapse.html
       fast/text/whitespace/pre-block-normal-inline-crash-1.html
       fast/text/whitespace/pre-block-normal-inline-crash-2.html

* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlock::LineBreaker::nextLineBreak): Collapse
whitespace before breaking. Avoid setting the break before the current
position.

LayoutTests:

* editing/deleting/delete-block-table-expected.txt:
* editing/execCommand/selectAll-expected.txt: Renamed from LayoutTests/platform/chromium/editing/execCommand/selectAll-expected.txt.
* fast/text/whitespace/inline-whitespace-wrapping-1-expected.html: Added.
* fast/text/whitespace/inline-whitespace-wrapping-1.html: Added.
* fast/text/whitespace/inline-whitespace-wrapping-2-expected.html: Added.
* fast/text/whitespace/inline-whitespace-wrapping-2.html: Added.
* fast/text/whitespace/inline-whitespace-wrapping-3-expected.html: Added.
* fast/text/whitespace/inline-whitespace-wrapping-3.html: Added.
* fast/text/whitespace/inline-whitespace-wrapping-4-expected.html: Added.
* fast/text/whitespace/inline-whitespace-wrapping-4.html: Added.
* fast/text/whitespace/nowrap-white-space-collapse-expected.html: Added.
* fast/text/whitespace/nowrap-white-space-collapse.html: Added.
* fast/text/whitespace/pre-block-normal-inline-crash-1-expected.txt: Added.
* fast/text/whitespace/pre-block-normal-inline-crash-1.html: Added.
* fast/text/whitespace/pre-block-normal-inline-crash-2-expected.txt: Added.
* fast/text/whitespace/pre-block-normal-inline-crash-2.html: Added.
* platform/chromium-win/editing/deleting/delete-to-select-table-expected.txt:
* platform/chromium-win/editing/execCommand/print-expected.txt:
* platform/chromium-win/editing/execCommand/selectAll-expected.txt:
* platform/chromium-win/editing/inserting/editable-html-element-expected.txt:
* platform/efl/editing/execCommand/selectAll-expected.txt: Removed.
* platform/gtk/editing/execCommand/selectAll-expected.txt: Removed.
* platform/mac/editing/execCommand/selectAll-expected.txt: Removed.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@138654 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 64db104..3a0f2c3 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,34 @@
+2013-01-02  Douglas Stockwell  <dstockwell@chromium.org>
+
+        Crash in WebCore::InlineBox::deleteLine
+        https://bugs.webkit.org/show_bug.cgi?id=93448
+
+        Reviewed by Eric Seidel.
+
+        * editing/deleting/delete-block-table-expected.txt:
+        * editing/execCommand/selectAll-expected.txt: Renamed from LayoutTests/platform/chromium/editing/execCommand/selectAll-expected.txt.
+        * fast/text/whitespace/inline-whitespace-wrapping-1-expected.html: Added.
+        * fast/text/whitespace/inline-whitespace-wrapping-1.html: Added.
+        * fast/text/whitespace/inline-whitespace-wrapping-2-expected.html: Added.
+        * fast/text/whitespace/inline-whitespace-wrapping-2.html: Added.
+        * fast/text/whitespace/inline-whitespace-wrapping-3-expected.html: Added.
+        * fast/text/whitespace/inline-whitespace-wrapping-3.html: Added.
+        * fast/text/whitespace/inline-whitespace-wrapping-4-expected.html: Added.
+        * fast/text/whitespace/inline-whitespace-wrapping-4.html: Added.
+        * fast/text/whitespace/nowrap-white-space-collapse-expected.html: Added.
+        * fast/text/whitespace/nowrap-white-space-collapse.html: Added.
+        * fast/text/whitespace/pre-block-normal-inline-crash-1-expected.txt: Added.
+        * fast/text/whitespace/pre-block-normal-inline-crash-1.html: Added.
+        * fast/text/whitespace/pre-block-normal-inline-crash-2-expected.txt: Added.
+        * fast/text/whitespace/pre-block-normal-inline-crash-2.html: Added.
+        * platform/chromium-win/editing/deleting/delete-to-select-table-expected.txt:
+        * platform/chromium-win/editing/execCommand/print-expected.txt:
+        * platform/chromium-win/editing/execCommand/selectAll-expected.txt:
+        * platform/chromium-win/editing/inserting/editable-html-element-expected.txt:
+        * platform/efl/editing/execCommand/selectAll-expected.txt: Removed.
+        * platform/gtk/editing/execCommand/selectAll-expected.txt: Removed.
+        * platform/mac/editing/execCommand/selectAll-expected.txt: Removed.
+
 2013-01-02  Ryosuke Niwa  <rniwa@webkit.org>
 
         Add a test expectation for the bug 105952.
diff --git a/LayoutTests/editing/deleting/delete-block-table-expected.txt b/LayoutTests/editing/deleting/delete-block-table-expected.txt
index 33d80f6..6cf0730 100644
--- a/LayoutTests/editing/deleting/delete-block-table-expected.txt
+++ b/LayoutTests/editing/deleting/delete-block-table-expected.txt
@@ -2,7 +2,7 @@
 
 Before
 Foo	 baz
-bar      	 buffalfter
+bar	 buffalfter
 execDeleteCommand: <div>Before</div> <table style="border:3px solid #aaa;"> <tbody><tr> <td> Foo </td> <td> baz </td> </tr> <tr> <td> bar </td> <td> buffalo </td> </tr> </tbody></table> <span id="start">fter</span>
 execDeleteCommand: <div>Before</div> <table style="border:3px solid #aaa;"> <tbody><tr> <td> Foo </td> <td> baz </td> </tr> <tr> <td> bar </td> <td> buffalofter</td></tr></tbody></table>
 execDeleteCommand: <div>Before</div> <table style="border:3px solid #aaa;"> <tbody><tr> <td> Foo </td> <td> baz </td> </tr> <tr> <td> bar </td> <td> buffalfter</td></tr></tbody></table>
diff --git a/LayoutTests/platform/efl/editing/execCommand/selectAll-expected.txt b/LayoutTests/editing/execCommand/selectAll-expected.txt
similarity index 100%
rename from LayoutTests/platform/efl/editing/execCommand/selectAll-expected.txt
rename to LayoutTests/editing/execCommand/selectAll-expected.txt
diff --git a/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-1-expected.html b/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-1-expected.html
new file mode 100644
index 0000000..b27e9ad
--- /dev/null
+++ b/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-1-expected.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<style>
+div {
+    font: 1em/1 Ahem;
+    width: 1em;
+}
+span {
+    color: lime;
+    background: lime;
+}
+.pre {
+    white-space: pre;
+}
+</style>
+This test passes if there is a green horizontal line below. It tests that an
+inline setting white-space:normal does allow word breaking just because it
+is nested in a block setting white-space:pre.<br>
+<div class="pre"><span>xxxxxxxxxxxxxxxxxx</span></div>
diff --git a/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-1.html b/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-1.html
new file mode 100644
index 0000000..fa1ff4c
--- /dev/null
+++ b/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-1.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<style>
+div {
+    font: 1em/1 Ahem;
+    width: 1em;
+}
+span {
+    color: lime;
+    background: lime;
+}
+.normal {
+    white-space: normal;
+}
+.pre {
+    white-space: pre;
+}
+</style>
+This test passes if there is a green horizontal line below. It tests that an
+inline setting white-space:normal does allow word breaking just because it
+is nested in a block setting white-space:pre.<br>
+<div class="pre"><span class="normal">xxxxxxxxxxxxxxxxxx</span></div>
diff --git a/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-2-expected.html b/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-2-expected.html
new file mode 100644
index 0000000..242ceb6
--- /dev/null
+++ b/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-2-expected.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<style>
+div {
+    font: 1em/1 Ahem;
+    width: 1em;
+}
+span {
+    color: lime;
+    background: lime;
+}
+.normal {
+    white-space: normal;
+}
+.pre {
+    white-space: pre;
+}
+</style>
+This test passes if there is a green horizontal line below. It tests that a break
+is not introduced just because an inline with white-space:pre ends in whitespace.<br>
+<div class="pre"><span>xxxx xxxx</span></div>
diff --git a/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-2.html b/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-2.html
new file mode 100644
index 0000000..8d320fb
--- /dev/null
+++ b/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-2.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<style>
+div {
+    font: 1em/1 Ahem;
+    width: 1em;
+}
+span {
+    color: lime;
+    background: lime;
+}
+.normal {
+    white-space: normal;
+}
+.pre {
+    white-space: pre;
+}
+</style>
+This test passes if there is a green horizontal line below. It tests that a break
+is not introduced just because an inline with white-space:pre ends in whitespace.<br>
+<div class="normal"><span class="pre">xxxx </span><span class="normal">xxxx</span></div>
diff --git a/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-3-expected.html b/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-3-expected.html
new file mode 100644
index 0000000..261fd2c
--- /dev/null
+++ b/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-3-expected.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<style>
+div {
+    font: 1em/1 Ahem;
+    width: 1em;
+}
+span {
+    color: lime;
+    background: lime;
+}
+.normal {
+    white-space: normal;
+}
+.pre {
+    white-space: pre;
+}
+</style>
+This test passes if there is a green square below. It tests that whitespace at the end of
+an inline setting white-space:pre is preserved.<br>
+<div class="pre"><span>x 
+xx</span></div>
diff --git a/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-3.html b/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-3.html
new file mode 100644
index 0000000..669bc99
--- /dev/null
+++ b/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-3.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<style>
+div {
+    font: 1em/1 Ahem;
+    width: 1em;
+}
+span {
+    color: lime;
+    background: lime;
+}
+.normal {
+    white-space: normal;
+}
+.pre {
+    white-space: pre;
+}
+</style>
+This test passes if there is a green square below. It tests that whitespace at the end of
+an inline setting white-space:pre is preserved.<br>
+<div class="normal"><span class="pre">x </span><span class="normal"> xx</span></div>
diff --git a/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-4-expected.html b/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-4-expected.html
new file mode 100644
index 0000000..bad9f75
--- /dev/null
+++ b/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-4-expected.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<style>
+div {
+    font: 1em/1 Ahem;
+    width: 1em;
+}
+span {
+    color: lime;
+    background: lime;
+}
+.normal {
+    white-space: normal;
+}
+.pre {
+    white-space: pre;
+}
+</style>
+This test passes if there is a green square below. It tests that whitespace at the end of
+an inline setting white-space:nowrap can be collapsed with a break at the start of the
+next inline.<br>
+<div class="pre"><span>xx
+xx</span></div>
diff --git a/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-4.html b/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-4.html
new file mode 100644
index 0000000..9641920
--- /dev/null
+++ b/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-4.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<style>
+div {
+    font: 1em/1 Ahem;
+    width: 1em;
+}
+span {
+    color: lime;
+    background: lime;
+}
+.normal {
+    white-space: normal;
+}
+.pre {
+    white-space: pre;
+}
+.nowrap {
+    white-space: nowrap;
+}
+</style>
+This test passes if there is a green square below. It tests that whitespace at the end of
+an inline setting white-space:nowrap can be collapsed with a break at the start of the
+next inline.<br>
+<div class="pre"><span class="nowrap">xx </span><span class="normal"> xx</span></div>
diff --git a/LayoutTests/fast/text/whitespace/nowrap-white-space-collapse-expected.html b/LayoutTests/fast/text/whitespace/nowrap-white-space-collapse-expected.html
new file mode 100644
index 0000000..3ea4ee3
--- /dev/null
+++ b/LayoutTests/fast/text/whitespace/nowrap-white-space-collapse-expected.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<style>
+div {
+    font: 1em/1 Ahem;
+    width: 1em;
+}
+span {
+    color: lime;
+    background: lime;
+}
+.pre {
+    white-space: pre;
+}
+</style>
+This test passes if there is a horizontal green line below. It tests that:
+<ul>
+<li>a block setting white-space:pre does not affect the whitespace-collapsing
+behavior of an inline setting white-space:nowrap</li>
+<li>an inline setting white-space:normal or nowrap does not allow wrapping
+when nested in a block that sets white-space:pre</li>
+</ul>
+<div class="test pre"><span>x xx</span></div>
diff --git a/LayoutTests/fast/text/whitespace/nowrap-white-space-collapse.html b/LayoutTests/fast/text/whitespace/nowrap-white-space-collapse.html
new file mode 100644
index 0000000..6bfe386f
--- /dev/null
+++ b/LayoutTests/fast/text/whitespace/nowrap-white-space-collapse.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<style>
+div {
+    font: 1em/1 Ahem;
+    width: 1em;
+}
+span {
+    color: lime;
+    background: lime;
+}
+.normal {
+    white-space: normal;
+}
+.nowrap {
+    white-space: nowrap;
+}
+.pre {
+    white-space: pre;
+}
+</style>
+This test passes if there is a horizontal green line below. It tests that:
+<ul>
+<li>a block setting white-space:pre does not affect the whitespace-collapsing
+behavior of an inline setting white-space:nowrap</li>
+<li>an inline setting white-space:normal or nowrap does not allow wrapping
+when nested in a block that sets white-space:pre</li>
+</ul>
+<div class="test pre"><span class="nowrap foo">x </span><span class="normal">xx</span></div>
diff --git a/LayoutTests/fast/text/whitespace/pre-block-normal-inline-crash-1-expected.txt b/LayoutTests/fast/text/whitespace/pre-block-normal-inline-crash-1-expected.txt
new file mode 100644
index 0000000..9729648
--- /dev/null
+++ b/LayoutTests/fast/text/whitespace/pre-block-normal-inline-crash-1-expected.txt
@@ -0,0 +1 @@
+This test passes if it does not CRASH.
diff --git a/LayoutTests/fast/text/whitespace/pre-block-normal-inline-crash-1.html b/LayoutTests/fast/text/whitespace/pre-block-normal-inline-crash-1.html
new file mode 100644
index 0000000..9bd0e6e
--- /dev/null
+++ b/LayoutTests/fast/text/whitespace/pre-block-normal-inline-crash-1.html
@@ -0,0 +1,22 @@
+<style>
+body {
+  margin-right: 100%;
+}
+.normal {
+  padding-left: 1px;
+  white-space: normal;
+  word-wrap: break-word;
+}
+.pre {
+  white-space: pre;
+}
+</style>
+<div class="pre"><span class="normal">
+This test passes if it does not CRASH.</span></div>
+<script>
+// Tests a case where an inline element that sets white-space:normal nested
+// in a block that sets white-space:pre works correctly when there is a
+// line break at the start of the inline element.
+if (window.testRunner)
+    testRunner.dumpAsText();
+</script>
diff --git a/LayoutTests/fast/text/whitespace/pre-block-normal-inline-crash-2-expected.txt b/LayoutTests/fast/text/whitespace/pre-block-normal-inline-crash-2-expected.txt
new file mode 100644
index 0000000..a79b43d
--- /dev/null
+++ b/LayoutTests/fast/text/whitespace/pre-block-normal-inline-crash-2-expected.txt
@@ -0,0 +1,2 @@
+This test passes if it does not CRASH.
+
diff --git a/LayoutTests/fast/text/whitespace/pre-block-normal-inline-crash-2.html b/LayoutTests/fast/text/whitespace/pre-block-normal-inline-crash-2.html
new file mode 100644
index 0000000..d476ccc
--- /dev/null
+++ b/LayoutTests/fast/text/whitespace/pre-block-normal-inline-crash-2.html
@@ -0,0 +1,34 @@
+<style>
+body {
+  margin-right: 100%;
+}
+.normal {
+  padding-left: 1px;
+  white-space: normal;
+  word-wrap: break-word;
+}
+.pre {
+  white-space: pre;
+}
+</style>
+<div id=id1 style="height:1000px"></div>
+<table>
+<div>
+<caption id=id5 style="-webkit-appearance: sliderthumb-vertical"></caption>
+<div class="pre"><span id=id3 class="normal">
+ This test passes if it does not CRASH.<span id=id4></span></span></div>
+</div>
+</table>
+</body>
+<script>
+id3.appendChild(id5);
+document.documentElement.offsetTop;
+id1.parentElement.removeChild(id1);
+document.documentElement.offsetTop;
+id4.appendChild(id5);
+// Tests a case where an inline element that sets white-space:normal nested
+// in a block that sets white-space:pre works correctly when there is a
+// line break at the start of the inline element.
+if (window.testRunner)
+    testRunner.dumpAsText();
+</script>
diff --git a/LayoutTests/platform/chromium-win/editing/deleting/delete-to-select-table-expected.txt b/LayoutTests/platform/chromium-win/editing/deleting/delete-to-select-table-expected.txt
index c09f5a9..a2aa97e 100644
--- a/LayoutTests/platform/chromium-win/editing/deleting/delete-to-select-table-expected.txt
+++ b/LayoutTests/platform/chromium-win/editing/deleting/delete-to-select-table-expected.txt
@@ -22,12 +22,6 @@
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 2 of DIV > BODY > HTML > #document to 2 of DIV > BODY > HTML > #document toDOMRange:range from 1 of DIV > BODY > HTML > #document to 2 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
@@ -48,9 +42,8 @@
                   text run at (1,1) width 21: "baz"
             RenderTableRow {TR} at (0,26) size 76x22
               RenderTableCell {TD} at (2,26) size 27x22 [r=1 c=0 rs=1 cs=1]
-                RenderText {#text} at (1,1) size 25x19
+                RenderText {#text} at (1,1) size 20x19
                   text run at (1,1) width 20: "bar"
-                  text run at (21,1) width 5: "      "
               RenderTableCell {TD} at (31,26) size 43x22 [r=1 c=1 rs=1 cs=1]
                 RenderText {#text} at (1,1) size 41x19
                   text run at (1,1) width 41: "buffalo"
diff --git a/LayoutTests/platform/chromium-win/editing/execCommand/print-expected.txt b/LayoutTests/platform/chromium-win/editing/execCommand/print-expected.txt
index 197a5e5..67b33af 100644
--- a/LayoutTests/platform/chromium-win/editing/execCommand/print-expected.txt
+++ b/LayoutTests/platform/chromium-win/editing/execCommand/print-expected.txt
@@ -33,7 +33,6 @@
               text run at (0,112) width 126: "ignore them. "
               text run at (126,112) width 278: "Because they change things. "
               text run at (404,112) width 342: "They push the human race forward."
-              text run at (746,112) width 10: "  "
               text run at (0,140) width 475: "And while some may see them as the crazy ones, "
               text run at (475,140) width 144: "we see genius. "
               text run at (619,140) width 117: "Because the"
diff --git a/LayoutTests/platform/chromium-win/editing/execCommand/selectAll-expected.txt b/LayoutTests/platform/chromium-win/editing/execCommand/selectAll-expected.txt
index b96a0a2..803d7a6 100644
--- a/LayoutTests/platform/chromium-win/editing/execCommand/selectAll-expected.txt
+++ b/LayoutTests/platform/chromium-win/editing/execCommand/selectAll-expected.txt
@@ -35,7 +35,6 @@
               text run at (0,112) width 126: "ignore them. "
               text run at (126,112) width 278: "Because they change things. "
               text run at (404,112) width 342: "They push the human race forward."
-              text run at (746,112) width 10: "  "
               text run at (0,140) width 475: "And while some may see them as the crazy ones, "
               text run at (475,140) width 144: "we see genius. "
               text run at (619,140) width 117: "Because the"
diff --git a/LayoutTests/platform/chromium-win/editing/inserting/editable-html-element-expected.txt b/LayoutTests/platform/chromium-win/editing/inserting/editable-html-element-expected.txt
index aca3bbf..e445350 100644
--- a/LayoutTests/platform/chromium-win/editing/inserting/editable-html-element-expected.txt
+++ b/LayoutTests/platform/chromium-win/editing/inserting/editable-html-element-expected.txt
@@ -7,7 +7,7 @@
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text > BODY > HTML > #document to 1 of #text > BODY > HTML > #document toDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 259 of #text > BODY > HTML > #document to 259 of #text > BODY > HTML > #document toDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
 layer at (0,0) size 800x600
@@ -21,8 +21,7 @@
           text run at (678,0) width 60: "inserting a"
           text run at (738,0) width 4: " "
           text run at (0,20) width 777: "paragraph separator doesn't split the body (inserting a paragraph separator usually splits/clones the enclosing block flow element)."
-        RenderText {#text} at (777,20) size 4x19
-          text run at (777,20) width 4: " "
+        RenderText {#text} at (0,0) size 0x0
       RenderBlock {DIV} at (0,40) size 784x20
         RenderBR {BR} at (0,0) size 0x19
 caret: position 0 of child 0 {BR} of child 2 {DIV} of body
diff --git a/LayoutTests/platform/chromium/editing/execCommand/selectAll-expected.txt b/LayoutTests/platform/chromium/editing/execCommand/selectAll-expected.txt
deleted file mode 100644
index 890cbe9..0000000
--- a/LayoutTests/platform/chromium/editing/execCommand/selectAll-expected.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 3 of DIV > BODY > HTML > #document
-EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > SPAN > DIV > BODY > HTML > #document to 562 of #text > P > SPAN > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-layer at (0,0) size 800x600
-  RenderView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  RenderBlock {HTML} at (0,0) size 800x600
-    RenderBody {BODY} at (8,8) size 784x584
-      RenderBlock {DIV} at (0,0) size 784x356 [border: (2px solid #FF0000)]
-        RenderBlock (anonymous) at (14,14) size 756x56
-          RenderInline {SPAN} at (0,0) size 693x56
-            RenderText {#text} at (0,0) size 693x56
-              text run at (0,0) width 687: "\"The quick brown fox jumps over the lazy dog\" uses every letter in the"
-              text run at (687,0) width 6: " "
-              text run at (0,28) width 170: "english language."
-        RenderBlock (anonymous) at (14,94) size 756x224
-          RenderBlock {P} at (0,0) size 756x224
-            RenderText {#text} at (0,0) size 756x224
-              text run at (0,0) width 462: "Here's to the crazy ones, the misfits, the rebels, "
-              text run at (462,0) width 193: "the trouble makers, "
-              text run at (655,0) width 92: "the round"
-              text run at (747,0) width 6: " "
-              text run at (0,28) width 243: "pegs in the square holes, "
-              text run at (243,28) width 350: "the ones who see things differently. "
-              text run at (593,28) width 144: "There not fond"
-              text run at (737,28) width 6: " "
-              text run at (0,56) width 510: "of rules, and they have no respect for the status quo, "
-              text run at (510,56) width 190: "you can quote then,"
-              text run at (0,84) width 197: "disagree with them, "
-              text run at (197,84) width 218: "glorify or vilify them, "
-              text run at (415,84) width 340: "about the only thing you can't do is"
-              text run at (755,84) width 1: " "
-              text run at (0,112) width 129: "ignore them. "
-              text run at (129,112) width 281: "Because they change things. "
-              text run at (410,112) width 344: "They push the human race forward."
-              text run at (754,112) width 2: "  "
-              text run at (0,140) width 481: "And while some may see them as the crazy ones, "
-              text run at (481,140) width 146: "we see genius. "
-              text run at (627,140) width 117: "Because the"
-              text run at (744,140) width 6: " "
-              text run at (0,168) width 632: "people who are crazy enough to think they can change the world "
-              text run at (632,168) width 116: "are the ones"
-              text run at (748,168) width 6: " "
-              text run at (0,196) width 77: "who do."
-        RenderBlock (anonymous) at (14,342) size 756x0
-          RenderInline {SPAN} at (0,0) size 0x0
-          RenderText {#text} at (0,0) size 0x0
-selection start: position 0 of child 0 {#text} of child 1 {SPAN} of child 1 {DIV} of body
-selection end:   position 562 of child 0 {#text} of child 1 {P} of child 1 {SPAN} of child 1 {DIV} of body
diff --git a/LayoutTests/platform/gtk/editing/execCommand/selectAll-expected.txt b/LayoutTests/platform/gtk/editing/execCommand/selectAll-expected.txt
deleted file mode 100644
index 890cbe9..0000000
--- a/LayoutTests/platform/gtk/editing/execCommand/selectAll-expected.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 3 of DIV > BODY > HTML > #document
-EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > SPAN > DIV > BODY > HTML > #document to 562 of #text > P > SPAN > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-layer at (0,0) size 800x600
-  RenderView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  RenderBlock {HTML} at (0,0) size 800x600
-    RenderBody {BODY} at (8,8) size 784x584
-      RenderBlock {DIV} at (0,0) size 784x356 [border: (2px solid #FF0000)]
-        RenderBlock (anonymous) at (14,14) size 756x56
-          RenderInline {SPAN} at (0,0) size 693x56
-            RenderText {#text} at (0,0) size 693x56
-              text run at (0,0) width 687: "\"The quick brown fox jumps over the lazy dog\" uses every letter in the"
-              text run at (687,0) width 6: " "
-              text run at (0,28) width 170: "english language."
-        RenderBlock (anonymous) at (14,94) size 756x224
-          RenderBlock {P} at (0,0) size 756x224
-            RenderText {#text} at (0,0) size 756x224
-              text run at (0,0) width 462: "Here's to the crazy ones, the misfits, the rebels, "
-              text run at (462,0) width 193: "the trouble makers, "
-              text run at (655,0) width 92: "the round"
-              text run at (747,0) width 6: " "
-              text run at (0,28) width 243: "pegs in the square holes, "
-              text run at (243,28) width 350: "the ones who see things differently. "
-              text run at (593,28) width 144: "There not fond"
-              text run at (737,28) width 6: " "
-              text run at (0,56) width 510: "of rules, and they have no respect for the status quo, "
-              text run at (510,56) width 190: "you can quote then,"
-              text run at (0,84) width 197: "disagree with them, "
-              text run at (197,84) width 218: "glorify or vilify them, "
-              text run at (415,84) width 340: "about the only thing you can't do is"
-              text run at (755,84) width 1: " "
-              text run at (0,112) width 129: "ignore them. "
-              text run at (129,112) width 281: "Because they change things. "
-              text run at (410,112) width 344: "They push the human race forward."
-              text run at (754,112) width 2: "  "
-              text run at (0,140) width 481: "And while some may see them as the crazy ones, "
-              text run at (481,140) width 146: "we see genius. "
-              text run at (627,140) width 117: "Because the"
-              text run at (744,140) width 6: " "
-              text run at (0,168) width 632: "people who are crazy enough to think they can change the world "
-              text run at (632,168) width 116: "are the ones"
-              text run at (748,168) width 6: " "
-              text run at (0,196) width 77: "who do."
-        RenderBlock (anonymous) at (14,342) size 756x0
-          RenderInline {SPAN} at (0,0) size 0x0
-          RenderText {#text} at (0,0) size 0x0
-selection start: position 0 of child 0 {#text} of child 1 {SPAN} of child 1 {DIV} of body
-selection end:   position 562 of child 0 {#text} of child 1 {P} of child 1 {SPAN} of child 1 {DIV} of body
diff --git a/LayoutTests/platform/mac/editing/execCommand/selectAll-expected.txt b/LayoutTests/platform/mac/editing/execCommand/selectAll-expected.txt
deleted file mode 100644
index 890cbe9..0000000
--- a/LayoutTests/platform/mac/editing/execCommand/selectAll-expected.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 3 of DIV > BODY > HTML > #document
-EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > SPAN > DIV > BODY > HTML > #document to 562 of #text > P > SPAN > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-layer at (0,0) size 800x600
-  RenderView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  RenderBlock {HTML} at (0,0) size 800x600
-    RenderBody {BODY} at (8,8) size 784x584
-      RenderBlock {DIV} at (0,0) size 784x356 [border: (2px solid #FF0000)]
-        RenderBlock (anonymous) at (14,14) size 756x56
-          RenderInline {SPAN} at (0,0) size 693x56
-            RenderText {#text} at (0,0) size 693x56
-              text run at (0,0) width 687: "\"The quick brown fox jumps over the lazy dog\" uses every letter in the"
-              text run at (687,0) width 6: " "
-              text run at (0,28) width 170: "english language."
-        RenderBlock (anonymous) at (14,94) size 756x224
-          RenderBlock {P} at (0,0) size 756x224
-            RenderText {#text} at (0,0) size 756x224
-              text run at (0,0) width 462: "Here's to the crazy ones, the misfits, the rebels, "
-              text run at (462,0) width 193: "the trouble makers, "
-              text run at (655,0) width 92: "the round"
-              text run at (747,0) width 6: " "
-              text run at (0,28) width 243: "pegs in the square holes, "
-              text run at (243,28) width 350: "the ones who see things differently. "
-              text run at (593,28) width 144: "There not fond"
-              text run at (737,28) width 6: " "
-              text run at (0,56) width 510: "of rules, and they have no respect for the status quo, "
-              text run at (510,56) width 190: "you can quote then,"
-              text run at (0,84) width 197: "disagree with them, "
-              text run at (197,84) width 218: "glorify or vilify them, "
-              text run at (415,84) width 340: "about the only thing you can't do is"
-              text run at (755,84) width 1: " "
-              text run at (0,112) width 129: "ignore them. "
-              text run at (129,112) width 281: "Because they change things. "
-              text run at (410,112) width 344: "They push the human race forward."
-              text run at (754,112) width 2: "  "
-              text run at (0,140) width 481: "And while some may see them as the crazy ones, "
-              text run at (481,140) width 146: "we see genius. "
-              text run at (627,140) width 117: "Because the"
-              text run at (744,140) width 6: " "
-              text run at (0,168) width 632: "people who are crazy enough to think they can change the world "
-              text run at (632,168) width 116: "are the ones"
-              text run at (748,168) width 6: " "
-              text run at (0,196) width 77: "who do."
-        RenderBlock (anonymous) at (14,342) size 756x0
-          RenderInline {SPAN} at (0,0) size 0x0
-          RenderText {#text} at (0,0) size 0x0
-selection start: position 0 of child 0 {#text} of child 1 {SPAN} of child 1 {DIV} of body
-selection end:   position 562 of child 0 {#text} of child 1 {P} of child 1 {SPAN} of child 1 {DIV} of body
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 409c665..87edb5e 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,42 @@
+2013-01-02  Douglas Stockwell  <dstockwell@chromium.org>
+
+        Crash in WebCore::InlineBox::deleteLine
+        https://bugs.webkit.org/show_bug.cgi?id=93448
+
+        Reviewed by Eric Seidel.
+
+        When we ran off the end of the line while looking for line breaks in an
+        inline with white-space:nowrap nested in a block with white-space:pre
+        it was possible for the line break to be set at or before the current
+        position -- this could result in duplications in the render tree or
+        infinite looping.
+
+        This patch changes the "fixup" logic that runs after we have finished
+        iterating through elements and text and have potentially found a break
+        point. In the case of a block setting white-space:pre we would back up
+        a character in some cases. Not doing so could leave whitespace that
+        should have been collapsed at the end of an inline.
+
+        For example in '<span style="white-space:nowrap">x_</span>_y' if a
+        break was inserted before 'y' the space after 'x' would still be
+        rendered (rather than be collapsed with the break).
+
+        To avoid this problem we will not take the opportunity to break until
+        we have finished collapsing whitespace.
+
+        Tests: fast/text/whitespace/inline-whitespace-wrapping-1.html
+               fast/text/whitespace/inline-whitespace-wrapping-2.html
+               fast/text/whitespace/inline-whitespace-wrapping-3.html
+               fast/text/whitespace/inline-whitespace-wrapping-4.html
+               fast/text/whitespace/nowrap-white-space-collapse.html
+               fast/text/whitespace/pre-block-normal-inline-crash-1.html
+               fast/text/whitespace/pre-block-normal-inline-crash-2.html
+
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::RenderBlock::LineBreaker::nextLineBreak): Collapse
+        whitespace before breaking. Avoid setting the break before the current
+        position.
+
 2013-01-02  Adam Barth  <abarth@webkit.org>
 
         Remove webkitPostMessage
diff --git a/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
index 1155fc1..4447686 100644
--- a/Source/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -2912,7 +2912,9 @@
                                     wordMeasurement.width = charWidth;
                                 }
                             }
-                            goto end; // Didn't fit. Jump to the end.
+                            // Didn't fit. Jump to the end unless there's still an opportunity to collapse whitespace.
+                            if (ignoringSpaces || !currentStyle->collapseWhiteSpace() || !currentCharacterIsSpace || !previousCharacterIsSpace)
+                                goto end;
                         } else {
                             if (!betweenWords || (midWordBreak && !autoWrap))
                                 width.addUncommittedWidth(-additionalTmpW);
@@ -3039,17 +3041,17 @@
         bool checkForBreak = autoWrap;
         if (width.committedWidth() && !width.fitsOnLine() && lBreak.m_obj && currWS == NOWRAP)
             checkForBreak = true;
-        else if (next && current.m_obj->isText() && next->isText() && !next->isBR() && (autoWrap || (next->style()->autoWrap()))) {
-            if (currentCharacterIsSpace)
+        else if (next && current.m_obj->isText() && next->isText() && !next->isBR() && (autoWrap || next->style()->autoWrap())) {
+            if (autoWrap && currentCharacterIsSpace)
                 checkForBreak = true;
             else {
                 RenderText* nextText = toRenderText(next);
                 if (nextText->textLength()) {
                     UChar c = nextText->characterAt(0);
-                    checkForBreak = (c == ' ' || c == '\t' || (c == '\n' && !next->preservesNewline()));
                     // If the next item on the line is text, and if we did not end with
                     // a space, then the next text run continues our word (and so it needs to
-                    // keep adding to |tmpW|. Just update and continue.
+                    // keep adding to the uncommitted width. Just update and continue.
+                    checkForBreak = !currentCharacterIsSpace && (c == ' ' || c == '\t' || (c == '\n' && !next->preservesNewline()));
                 } else if (nextText->isWordBreak())
                     checkForBreak = true;
 
@@ -3108,15 +3110,8 @@
  end:
     if (lBreak == resolver.position() && (!lBreak.m_obj || !lBreak.m_obj->isBR())) {
         // we just add as much as possible
-        if (blockStyle->whiteSpace() == PRE) {
-            // FIXME: Don't really understand this case.
-            if (current.m_pos) {
-                // FIXME: This should call moveTo which would clear m_nextBreakablePosition
-                // this code as-is is likely wrong.
-                lBreak.m_obj = current.m_obj;
-                lBreak.m_pos = current.m_pos - 1;
-            } else
-                lBreak.moveTo(last, last->isText() ? last->length() : 0);
+        if (blockStyle->whiteSpace() == PRE && !current.m_pos) {
+            lBreak.moveTo(last, last->isText() ? last->length() : 0);
         } else if (lBreak.m_obj) {
             // Don't ever break in the middle of a word if we can help it.
             // There's no room at all. We just have to be on this line,