<rdar://problem/9190108> Crash when hiding a float
authormitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 16 Apr 2011 21:59:36 +0000 (21:59 +0000)
committermitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 16 Apr 2011 21:59:36 +0000 (21:59 +0000)
Reviewed by Simon Fraser.

Source/WebCore:

Test: fast/block/float/overhanging-tall-block.html

* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::addOverhangingFloats): Moved the call to childLogicalTop() out of the loop.
Capped the logical bottom so that we get the correct maximum.
* rendering/RenderBlock.h: Decleared appendFloatingObjectToLastLine().
* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlock::appendFloatingObjectToLastLine): Added. Ensures correct bookkeeping by
extending the float if needed so that it touches the line.
(WebCore::RenderBlock::layoutInlineChildren): Changed to call appendFloatingObjectToLastLine().
(WebCore::RenderBlock::checkFloatsInCleanLine): Capped the float height so the we mark the right
range of lines as dirty.
* rendering/RootInlineBox.h:
(WebCore::RootInlineBox::appendFloat): Replaced the floats() accessor with this function, which
allows the creation of the vector to be combined with appending the first float.

LayoutTests:

* fast/block/float/overhanging-tall-block.html: Added.
* platform/mac/fast/block/float/overhanging-tall-block-expected.checksum: Added.
* platform/mac/fast/block/float/overhanging-tall-block-expected.png: Added.
* platform/mac/fast/block/float/overhanging-tall-block-expected.txt: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@84096 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/block/float/overhanging-tall-block.html [new file with mode: 0755]
LayoutTests/platform/mac/fast/block/float/overhanging-tall-block-expected.checksum [new file with mode: 0644]
LayoutTests/platform/mac/fast/block/float/overhanging-tall-block-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/fast/block/float/overhanging-tall-block-expected.txt [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderBlock.h
Source/WebCore/rendering/RenderBlockLineLayout.cpp
Source/WebCore/rendering/RootInlineBox.h

index e24a966..55647e4 100644 (file)
@@ -1,3 +1,14 @@
+2011-04-16  Dan Bernstein  <mitz@apple.com>
+
+        Reviewed by Simon Fraser.
+
+        <rdar://problem/9190108> Crash when hiding a float
+
+        * fast/block/float/overhanging-tall-block.html: Added.
+        * platform/mac/fast/block/float/overhanging-tall-block-expected.checksum: Added.
+        * platform/mac/fast/block/float/overhanging-tall-block-expected.png: Added.
+        * platform/mac/fast/block/float/overhanging-tall-block-expected.txt: Added.
+
 2011-04-16  Simon Fraser  <simon.fraser@apple.com>
 
         Fix border drawing tests to drop -webkit prefix on border-radius, and make the tests compatible with Firefox
diff --git a/LayoutTests/fast/block/float/overhanging-tall-block.html b/LayoutTests/fast/block/float/overhanging-tall-block.html
new file mode 100755 (executable)
index 0000000..ea3220f
--- /dev/null
@@ -0,0 +1,13 @@
+<body style="overflow: hidden;">
+    <div><textarea rows="100000000"></textarea></div>
+    <div>
+        <textarea style="display: block; width: 100%" rows="100000000"></textarea>
+        <div id="target" style="display: inline-block; width: 300px; height: 150px; float: left;"></div>
+        <textarea style="display: block;" rows="100000000"></textarea>
+    </div>
+    <div></div>
+    <script>
+        document.body.offsetTop;
+        document.getElementById("target").style.display = "none";
+    </script>
+</body>
diff --git a/LayoutTests/platform/mac/fast/block/float/overhanging-tall-block-expected.checksum b/LayoutTests/platform/mac/fast/block/float/overhanging-tall-block-expected.checksum
new file mode 100644 (file)
index 0000000..1b66181
--- /dev/null
@@ -0,0 +1 @@
+6a0ac04cdbf56a95c04c2558bc76e7ec
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/block/float/overhanging-tall-block-expected.png b/LayoutTests/platform/mac/fast/block/float/overhanging-tall-block-expected.png
new file mode 100644 (file)
index 0000000..2b8a329
Binary files /dev/null and b/LayoutTests/platform/mac/fast/block/float/overhanging-tall-block-expected.png differ
diff --git a/LayoutTests/platform/mac/fast/block/float/overhanging-tall-block-expected.txt b/LayoutTests/platform/mac/fast/block/float/overhanging-tall-block-expected.txt
new file mode 100644 (file)
index 0000000..cd22439
--- /dev/null
@@ -0,0 +1,11 @@
+layer at (0,0) size 800x1300000028
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x1300000028 backgroundClip at (0,0) size 800x1073741823 clip at (0,0) size 800x1073741823 outlineClip at (0,0) size 800x1073741823
+  RenderBlock {HTML} at (0,0) size 800x1300000028
+    RenderBody {BODY} at (8,8) size 784x1300000012
+      RenderBlock {DIV} at (0,0) size 784x1300000010
+      RenderBlock {DIV} at (0,1300000012) size 784x0
+      RenderBlock {DIV} at (0,1300000014) size 784x0
+layer at (10,10) size 161x1300000006 backgroundClip at (10,10) size 161x1073741813 clip at (11,11) size 159x1073741812 outlineClip at (0,0) size 800x1073741823
+  RenderTextControl {TEXTAREA} at (2,2) size 161x1300000006 [bgcolor=#FFFFFF] [border: (1px solid #000000)]
+    RenderBlock {DIV} at (3,3) size 155x13
index f48ba79..9f58224 100644 (file)
@@ -1,3 +1,25 @@
+2011-04-16  Dan Bernstein  <mitz@apple.com>
+
+        Reviewed by Simon Fraser.
+
+        <rdar://problem/9190108> Crash when hiding a float
+
+        Test: fast/block/float/overhanging-tall-block.html
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::addOverhangingFloats): Moved the call to childLogicalTop() out of the loop.
+        Capped the logical bottom so that we get the correct maximum.
+        * rendering/RenderBlock.h: Decleared appendFloatingObjectToLastLine().
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::RenderBlock::appendFloatingObjectToLastLine): Added. Ensures correct bookkeeping by
+        extending the float if needed so that it touches the line.
+        (WebCore::RenderBlock::layoutInlineChildren): Changed to call appendFloatingObjectToLastLine().
+        (WebCore::RenderBlock::checkFloatsInCleanLine): Capped the float height so the we mark the right
+        range of lines as dirty.
+        * rendering/RootInlineBox.h:
+        (WebCore::RootInlineBox::appendFloat): Replaced the floats() accessor with this function, which
+        allows the creation of the vector to be combined with appending the first float.
+
 2011-04-16  Sam Weinig  <sam@webkit.org>
 
         Reviewed by Simon Fraser.
index 0c4f1a1..6ae2ae5 100644 (file)
@@ -3650,6 +3650,7 @@ int RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset,
     if (child->hasOverflowClip() || !child->containsFloats() || child->isRoot() || child->hasColumns() || child->isWritingModeRoot())
         return 0;
 
+    int childLogicalTop = child->logicalTop();
     int lowestFloatLogicalBottom = 0;
 
     // Floats that will remain the child's responsibility to paint should factor into its
@@ -3657,7 +3658,8 @@ int RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset,
     FloatingObjectSetIterator childEnd = child->m_floatingObjects->set().end();
     for (FloatingObjectSetIterator childIt = child->m_floatingObjects->set().begin(); childIt != childEnd; ++childIt) {
         FloatingObject* r = *childIt;
-        int logicalBottom = child->logicalTop() + logicalBottomForFloat(r);
+        int logicalBottomForFloat = min(this->logicalBottomForFloat(r), numeric_limits<int>::max() - childLogicalTop);
+        int logicalBottom = childLogicalTop + logicalBottomForFloat;
         lowestFloatLogicalBottom = max(lowestFloatLogicalBottom, logicalBottom);
 
         if (logicalBottom > logicalHeight()) {
index 2b16acc..75d93e9 100644 (file)
@@ -511,6 +511,7 @@ private:
     // Positions new floats and also adjust all floats encountered on the line if any of them
     // have to move to the next page/column.
     bool positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineWidth&);
+    void appendFloatingObjectToLastLine(FloatingObject*);
 
     // End of functions defined in RenderBlockLineLayout.cpp.
 
index 43bec4f..09fc8b1 100644 (file)
@@ -714,6 +714,15 @@ inline BidiRun* RenderBlock::handleTrailingSpaces(BidiRunList<BidiRun>& bidiRuns
     return trailingSpaceRun;
 }
 
+void RenderBlock::appendFloatingObjectToLastLine(FloatingObject* floatingObject)
+{
+    // Ensure that the float touches the line.
+    if (logicalBottomForFloat(floatingObject) < lastRootBox()->blockLogicalHeight())
+        setLogicalHeightForFloat(floatingObject, lastRootBox()->blockLogicalHeight() - logicalTopForFloat(floatingObject));
+
+    lastRootBox()->appendFloat(floatingObject->renderer());
+}
+
 void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogicalTop, int& repaintLogicalBottom)
 {
     bool useRepaintBounds = false;
@@ -998,7 +1007,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
                 }
                 for (; it != end; ++it) {
                     FloatingObject* f = *it;
-                    lastRootBox()->floats().append(f->m_renderer);
+                    appendFloatingObjectToLastLine(f);
                     ASSERT(f->m_renderer == floats[floatIndex].object);
                     // If a float's geometry has changed, give up on syncing with clean lines.
                     if (floats[floatIndex].rect != f->frameRect())
@@ -1080,7 +1089,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
                 it = lastFloatIterator;
             }
             for (; it != end; ++it)
-                lastRootBox()->floats().append((*it)->m_renderer);
+                appendFloatingObjectToLastLine(*it);
             lastFloat = !floatingObjectSet.isEmpty() ? floatingObjectSet.last() : 0;
         }
         size_t floatCount = floats.size();
@@ -1138,6 +1147,7 @@ void RenderBlock::checkFloatsInCleanLine(RootInlineBox* line, Vector<FloatWithRe
             int floatTop = isHorizontalWritingMode() ? floats[floatIndex].rect.y() : floats[floatIndex].rect.x();
             int floatHeight = isHorizontalWritingMode() ? max(floats[floatIndex].rect.height(), newSize.height()) 
                                                                  : max(floats[floatIndex].rect.width(), newSize.width());
+            floatHeight = min(floatHeight, numeric_limits<int>::max() - floatTop);
             line->markDirty();
             markLinesDirtyInBlockRange(line->blockLogicalHeight(), floatTop + floatHeight, line);
             floats[floatIndex].rect.setSize(newSize);
index 36ee1f8..2564d85 100644 (file)
@@ -111,12 +111,13 @@ public:
 
     InlineBox* closestLeafChildForLogicalLeftPosition(int, bool onlyEditableLeaves = false);
 
-    Vector<RenderBox*>& floats()
+    void appendFloat(RenderBox* floatingBox)
     {
         ASSERT(!isDirty());
-        if (!m_floats)
-            m_floats= adoptPtr(new Vector<RenderBox*>);
-        return *m_floats;
+        if (m_floats)
+            m_floats->append(floatingBox);
+        else
+            m_floats= adoptPtr(new Vector<RenderBox*>(1, floatingBox));
     }
 
     Vector<RenderBox*>* floatsPtr() { ASSERT(!isDirty()); return m_floats.get(); }