Title: [122128] branches/chromium/1132

Diff

Copied: branches/chromium/1132/LayoutTests/fast/block/percent-height-descendant-not-removed-crash2-expected.txt (from rev 120862, trunk/LayoutTests/fast/block/percent-height-descendant-not-removed-crash2-expected.txt) (0 => 122128)


--- branches/chromium/1132/LayoutTests/fast/block/percent-height-descendant-not-removed-crash2-expected.txt	                        (rev 0)
+++ branches/chromium/1132/LayoutTests/fast/block/percent-height-descendant-not-removed-crash2-expected.txt	2012-07-09 19:04:51 UTC (rev 122128)
@@ -0,0 +1,2 @@
+WebKit bug 88017 - Crash due to renderer not removed from height descendant map.
+PASS. WebKit didn't crash.

Copied: branches/chromium/1132/LayoutTests/fast/block/percent-height-descendant-not-removed-crash2.html (from rev 120862, trunk/LayoutTests/fast/block/percent-height-descendant-not-removed-crash2.html) (0 => 122128)


--- branches/chromium/1132/LayoutTests/fast/block/percent-height-descendant-not-removed-crash2.html	                        (rev 0)
+++ branches/chromium/1132/LayoutTests/fast/block/percent-height-descendant-not-removed-crash2.html	2012-07-09 19:04:51 UTC (rev 122128)
@@ -0,0 +1,32 @@
+<html>
+<head>
+<style>
+#test1 { 
+    height: 1px; 
+    -webkit-writing-mode: vertical-rl;
+}
+#test1:nth-child(3) { 
+    height: auto; 
+}
+</style>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+ 
+_onload_ = function() {
+    document.body.appendChild(document.createElement('form'));
+    test1 = document.createElement('input');
+    test1.setAttribute('id', 'test1');
+    test1.setAttribute('type', 'range');
+    document.body.appendChild(test1);
+    document.designMode = 'on';
+    document.execCommand('selectall');
+    document.execCommand('FormatBlock', false, '<'+'pre>');
+    document.body.offsetTop;
+    document.body.innerHTML = "WebKit bug 88017 - Crash due to renderer not removed from height descendant map.<br />PASS. WebKit didn't crash.";
+}
+</script>
+</head>
+<body>
+</body>
+</html>
\ No newline at end of file

Modified: branches/chromium/1132/Source/WebCore/rendering/RenderBlock.cpp (122127 => 122128)


--- branches/chromium/1132/Source/WebCore/rendering/RenderBlock.cpp	2012-07-09 19:04:03 UTC (rev 122127)
+++ branches/chromium/1132/Source/WebCore/rendering/RenderBlock.cpp	2012-07-09 19:04:51 UTC (rev 122128)
@@ -3872,17 +3872,49 @@
     return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
 }
 
-#if !ASSERT_DISABLED
+bool RenderBlock::hasPercentHeightContainerMap()
+{
+    return gPercentHeightContainerMap;
+}
+
 bool RenderBlock::hasPercentHeightDescendant(RenderBox* descendant)
 {
-    ASSERT(descendant);
-    if (!gPercentHeightContainerMap)
-        return false;
-    HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->take(descendant);
-    return containerSet && containerSet->size();
+    // We don't null check gPercentHeightContainerMap since the caller
+    // already ensures this and we need to call this function on every
+    // descendant in clearPercentHeightDescendantsFrom().
+    ASSERT(gPercentHeightContainerMap);
+    return gPercentHeightContainerMap->contains(descendant);
 }
-#endif
 
+void RenderBlock::removePercentHeightDescendantIfNeeded(RenderBox* descendant)
+{
+    // We query the map directly, rather than looking at style's
+    // logicalHeight()/logicalMinHeight()/logicalMaxHeight() since those
+    // can change with writing mode/directional changes.
+    if (!hasPercentHeightContainerMap())
+        return;
+
+    if (!hasPercentHeightDescendant(descendant))
+        return;
+
+    removePercentHeightDescendant(descendant);
+}
+
+void RenderBlock::clearPercentHeightDescendantsFrom(RenderBox* parent)
+{
+    ASSERT(gPercentHeightContainerMap);
+    for (RenderObject* curr = parent->firstChild(); curr; curr = curr->nextInPreOrder(parent)) {
+        if (!curr->isBox())
+            continue;
+ 
+        RenderBox* box = toRenderBox(curr);
+        if (!hasPercentHeightDescendant(box))
+            continue;
+
+        removePercentHeightDescendant(box);
+    }
+}
+
 template <RenderBlock::FloatingObject::Type FloatTypeValue>
 inline void RenderBlock::FloatIntervalSearchAdapter<FloatTypeValue>::collectIfNeeded(const IntervalType& interval) const
 {

Modified: branches/chromium/1132/Source/WebCore/rendering/RenderBlock.h (122127 => 122128)


--- branches/chromium/1132/Source/WebCore/rendering/RenderBlock.h	2012-07-09 19:04:03 UTC (rev 122127)
+++ branches/chromium/1132/Source/WebCore/rendering/RenderBlock.h	2012-07-09 19:04:51 UTC (rev 122128)
@@ -108,9 +108,10 @@
     void addPercentHeightDescendant(RenderBox*);
     static void removePercentHeightDescendant(RenderBox*);
     HashSet<RenderBox*>* percentHeightDescendants() const;
-#if !ASSERT_DISABLED
+    static bool hasPercentHeightContainerMap();
     static bool hasPercentHeightDescendant(RenderBox*);
-#endif
+    static void clearPercentHeightDescendantsFrom(RenderBox*);
+    static void removePercentHeightDescendantIfNeeded(RenderBox*);
 
     void setHasMarkupTruncation(bool b) { m_hasMarkupTruncation = b; }
     bool hasMarkupTruncation() const { return m_hasMarkupTruncation; }

Modified: branches/chromium/1132/Source/WebCore/rendering/RenderBox.cpp (122127 => 122128)


--- branches/chromium/1132/Source/WebCore/rendering/RenderBox.cpp	2012-07-09 19:04:03 UTC (rev 122127)
+++ branches/chromium/1132/Source/WebCore/rendering/RenderBox.cpp	2012-07-09 19:04:51 UTC (rev 122128)
@@ -249,24 +249,17 @@
 {
     clearOverrideSize();
 
-    RenderStyle* styleToUse = style();
-    if (styleToUse && (styleToUse->logicalHeight().isPercent() || styleToUse->logicalMinHeight().isPercent() || styleToUse->logicalMaxHeight().isPercent()))
-        RenderBlock::removePercentHeightDescendant(this);
+    if (style()) {
+        RenderBlock::removePercentHeightDescendantIfNeeded(this);
 
-    if (styleToUse) {
         if (RenderView* view = this->view()) {
             if (FrameView* frameView = view->frameView()) {
-                if (styleToUse->position() == FixedPosition)
+                if (style()->position() == FixedPosition)
                     frameView->removeFixedObject();
             }
         }
     }
 
-    // If the following assertion fails, logicalHeight()/logicalMinHeight()/
-    // logicalMaxHeight() values are changed from a percent value to a non-percent
-    // value during laying out. It causes a use-after-free bug.
-    ASSERT(!RenderBlock::hasPercentHeightDescendant(this));
-
     RenderBoxModelObject::willBeDestroyed();
 }
 
@@ -347,12 +340,16 @@
 
 void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
 {
+    // Horizontal writing mode definition is updated in RenderBoxModelObject::updateBoxModelInfoFromStyle,
+    // (as part of the RenderBoxModelObject::styleDidChange call below). So, we can safely cache the horizontal
+    // writing mode value before style change here.
+    bool oldHorizontalWritingMode = isHorizontalWritingMode();
+
     RenderBoxModelObject::styleDidChange(diff, oldStyle);
 
     RenderStyle* newStyle = style();
     if (needsLayout() && oldStyle) {
-        if (oldStyle && (oldStyle->logicalHeight().isPercent() || oldStyle->logicalMinHeight().isPercent() || oldStyle->logicalMaxHeight().isPercent()))
-            RenderBlock::removePercentHeightDescendant(this);
+        RenderBlock::removePercentHeightDescendantIfNeeded(this);
 
         // Normally we can do optimized positioning layout for absolute/fixed positioned objects. There is one special case, however, which is
         // when the positioned object's margin-before is changed. In this case the parent has to get a layout in order to run margin collapsing
@@ -362,6 +359,10 @@
             parent()->setChildNeedsLayout(true);
     }
 
+    if (RenderBlock::hasPercentHeightContainerMap() && firstChild()
+        && oldHorizontalWritingMode != isHorizontalWritingMode())
+        RenderBlock::clearPercentHeightDescendantsFrom(this);
+
     // If our zoom factor changes and we have a defined scrollLeft/Top, we need to adjust that value into the
     // new zoomed coordinate space.
     if (hasOverflowClip() && oldStyle && newStyle && oldStyle->effectiveZoom() != newStyle->effectiveZoom()) {
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to