Title: [122128] branches/chromium/1132
- Revision
- 122128
- Author
- [email protected]
- Date
- 2012-07-09 12:04:51 -0700 (Mon, 09 Jul 2012)
Log Message
Merge 120862
BUG=130595
Review URL: https://chromiumcodereview.appspot.com/10756009
Modified Paths
Added Paths
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