Title: [164928] trunk/Source/WebCore
Revision
164928
Author
[email protected]
Date
2014-03-01 15:22:56 -0800 (Sat, 01 Mar 2014)

Log Message

Improve "bad parent" and "bad child list" assertions in line boxes
https://bugs.webkit.org/show_bug.cgi?id=125656

Reviewed by Sam Weinig.

My previous fix for this problem was incomplete. This continuation of that fix addresses
the flaw in the original and adds additional lifetime checking so problems can be seen in
debug builds without a memory debugger.

* rendering/InlineBox.cpp:
(WebCore::InlineBox::assertNotDeleted): Added. Poor man's memory debugging helper.
(WebCore::InlineBox::~InlineBox): Refactored body into a new function named
invalidateParentChildList. Added code to update the deletion sentinel to record
that this object is deleted.
(WebCore::InlineBox::setHasBadParent): Moved here from header since this debug-only
feature does not need to be inlined. Added a call to assertNotDeleted.
(WebCore::InlineBox::invalidateParentChildList): Added. Refactored from the destructor,
this is used by RenderTextLineBoxes.

* rendering/InlineBox.h: Added the deletion sentinel, and called it in the parent
function. Also changed the expansion/setExpansion functions to use the type name "int",
since we don't use the type name "signed" in the WebKit coding style.

* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::~InlineFlowBox): Call setHasBadChildList rather than doing the
setHasBadParent work on children directly, to avoid code duplication.
(WebCore::InlineFlowBox::setHasBadChildList): Moved here from header. Added code to set
"has bad parent" on all children, something we previously did only on destruction. Also
added assertNotDeleted.
(WebCore::InlineFlowBox::checkConsistency): Added call to assertNotDeleted. Also tweaked
code style and variable names a little bit.

* rendering/InlineFlowBox.h: Moved setHasBadChildList out of the header when it's on.
The empty version for ASSERT_WITH_SECURITY_IMPLICATION_DISABLED is still in the header.

* rendering/RenderTextLineBoxes.cpp:
(WebCore::RenderTextLineBoxes::invalidateParentChildLists): Call the new
InlineBox::invalidateParentChildList function instead of calling setHasBadChildList directly.
The new function checks m_hasBadParent, something we couldn't do here.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (164927 => 164928)


--- trunk/Source/WebCore/ChangeLog	2014-03-01 23:05:02 UTC (rev 164927)
+++ trunk/Source/WebCore/ChangeLog	2014-03-01 23:22:56 UTC (rev 164928)
@@ -1,3 +1,45 @@
+2014-03-01  Darin Adler  <[email protected]>
+
+        Improve "bad parent" and "bad child list" assertions in line boxes
+        https://bugs.webkit.org/show_bug.cgi?id=125656
+
+        Reviewed by Sam Weinig.
+
+        My previous fix for this problem was incomplete. This continuation of that fix addresses
+        the flaw in the original and adds additional lifetime checking so problems can be seen in
+        debug builds without a memory debugger.
+
+        * rendering/InlineBox.cpp:
+        (WebCore::InlineBox::assertNotDeleted): Added. Poor man's memory debugging helper.
+        (WebCore::InlineBox::~InlineBox): Refactored body into a new function named
+        invalidateParentChildList. Added code to update the deletion sentinel to record
+        that this object is deleted.
+        (WebCore::InlineBox::setHasBadParent): Moved here from header since this debug-only
+        feature does not need to be inlined. Added a call to assertNotDeleted.
+        (WebCore::InlineBox::invalidateParentChildList): Added. Refactored from the destructor,
+        this is used by RenderTextLineBoxes.
+
+        * rendering/InlineBox.h: Added the deletion sentinel, and called it in the parent
+        function. Also changed the expansion/setExpansion functions to use the type name "int",
+        since we don't use the type name "signed" in the WebKit coding style.
+
+        * rendering/InlineFlowBox.cpp:
+        (WebCore::InlineFlowBox::~InlineFlowBox): Call setHasBadChildList rather than doing the
+        setHasBadParent work on children directly, to avoid code duplication.
+        (WebCore::InlineFlowBox::setHasBadChildList): Moved here from header. Added code to set
+        "has bad parent" on all children, something we previously did only on destruction. Also
+        added assertNotDeleted.
+        (WebCore::InlineFlowBox::checkConsistency): Added call to assertNotDeleted. Also tweaked
+        code style and variable names a little bit.
+
+        * rendering/InlineFlowBox.h: Moved setHasBadChildList out of the header when it's on.
+        The empty version for ASSERT_WITH_SECURITY_IMPLICATION_DISABLED is still in the header.
+
+        * rendering/RenderTextLineBoxes.cpp:
+        (WebCore::RenderTextLineBoxes::invalidateParentChildLists): Call the new
+        InlineBox::invalidateParentChildList function instead of calling setHasBadChildList directly.
+        The new function checks m_hasBadParent, something we couldn't do here.
+
 2014-03-01  Benjamin Poulain  <[email protected]>
 
         Optimized querySelector(All) when selector contains #id

Modified: trunk/Source/WebCore/rendering/InlineBox.cpp (164927 => 164928)


--- trunk/Source/WebCore/rendering/InlineBox.cpp	2014-03-01 23:05:02 UTC (rev 164927)
+++ trunk/Source/WebCore/rendering/InlineBox.cpp	2014-03-01 23:22:56 UTC (rev 164928)
@@ -43,6 +43,7 @@
     float c;
     uint32_t d : 32;
 #if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED
+    unsigned s;
     bool f;
 #endif
 };
@@ -50,11 +51,31 @@
 COMPILE_ASSERT(sizeof(InlineBox) == sizeof(SameSizeAsInlineBox), InlineBox_size_guard);
 
 #if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED
+
+void InlineBox::assertNotDeleted() const
+{
+    ASSERT(m_deletionSentinel == deletionSentinelNotDeletedValue);
+}
+
 InlineBox::~InlineBox()
 {
+    invalidateParentChildList();
+    m_deletionSentinel = deletionSentinelDeletedValue;
+}
+
+void InlineBox::setHasBadParent()
+{
+    assertNotDeleted();
+    m_hasBadParent = true;
+}
+
+void InlineBox::invalidateParentChildList()
+{
+    assertNotDeleted();
     if (!m_hasBadParent && m_parent)
         m_parent->setHasBadChildList();
 }
+
 #endif
 
 void InlineBox::removeFromParent()
@@ -64,6 +85,7 @@
 }
 
 #ifndef NDEBUG
+
 const char* InlineBox::boxName() const
 {
     return "InlineBox";
@@ -101,6 +123,7 @@
         fputc(' ', stderr);
     fprintf(stderr, "\t%s %p\n", renderer().renderName(), &renderer());
 }
+
 #endif
 
 float InlineBox::logicalHeight() const

Modified: trunk/Source/WebCore/rendering/InlineBox.h (164927 => 164928)


--- trunk/Source/WebCore/rendering/InlineBox.h	2014-03-01 23:05:02 UTC (rev 164927)
+++ trunk/Source/WebCore/rendering/InlineBox.h	2014-03-01 23:22:56 UTC (rev 164928)
@@ -37,6 +37,8 @@
 public:
     virtual ~InlineBox();
 
+    void assertNotDeleted() const;
+
     virtual void deleteLine() = 0;
     virtual void extractLine() = 0;
     virtual void attachLine() = 0;
@@ -69,7 +71,6 @@
     virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) = 0;
     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom) = 0;
 
-public:
 #ifndef NDEBUG
     void showTreeForThis() const;
     void showLineTreeForThis() const;
@@ -148,6 +149,7 @@
 
     InlineFlowBox* parent() const
     {
+        assertNotDeleted();
         ASSERT_WITH_SECURITY_IMPLICATION(!m_hasBadParent);
         return m_parent;
     }
@@ -237,6 +239,7 @@
 
 #if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED
     void setHasBadParent();
+    void invalidateParentChildList();
 #endif
 
     int expansion() const { return m_bitfields.expansion(); }
@@ -368,6 +371,7 @@
         , m_renderer(renderer)
         , m_logicalWidth(0)
 #if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED
+        , m_deletionSentinel(deletionSentinelNotDeletedValue)
         , m_hasBadParent(false)
 #endif
     {
@@ -383,6 +387,7 @@
         , m_logicalWidth(logicalWidth)
         , m_bitfields(firstLine, constructed, dirty, extracted, isHorizontal)
 #if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED
+        , m_deletionSentinel(deletionSentinelNotDeletedValue)
         , m_hasBadParent(false)
 #endif
     {
@@ -401,14 +406,17 @@
     void setHasHyphen(bool hasHyphen) { m_bitfields.setHasEllipsisBoxOrHyphen(hasHyphen); }    
     bool canHaveLeadingExpansion() const { return m_bitfields.hasSelectedChildrenOrCanHaveLeadingExpansion(); }
     void setCanHaveLeadingExpansion(bool canHaveLeadingExpansion) { m_bitfields.setHasSelectedChildrenOrCanHaveLeadingExpansion(canHaveLeadingExpansion); }
-    signed expansion() { return m_bitfields.expansion(); }
-    void setExpansion(signed expansion) { m_bitfields.setExpansion(expansion); }
+    int expansion() { return m_bitfields.expansion(); }
+    void setExpansion(int expansion) { m_bitfields.setExpansion(expansion); }
     
     // For InlineFlowBox and InlineTextBox
     bool extracted() const { return m_bitfields.extracted(); }
 
 #if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED
 private:
+    static const unsigned deletionSentinelNotDeletedValue = 0xF0F0F0F0U;
+    static const unsigned deletionSentinelDeletedValue = 0xF0DEADF0U;
+    unsigned m_deletionSentinel;
     bool m_hasBadParent;
 #endif
 };
@@ -417,16 +425,15 @@
     TYPE_CASTS_BASE(ToValueTypeName, InlineBox, object, object->predicate, object.predicate)
 
 #if ASSERT_WITH_SECURITY_IMPLICATION_DISABLED
+
 inline InlineBox::~InlineBox()
 {
 }
-#endif
 
-#if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED
-inline void InlineBox::setHasBadParent()
+inline void InlineBox::assertNotDeleted() const
 {
-    m_hasBadParent = true;
 }
+
 #endif
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/InlineFlowBox.cpp (164927 => 164928)


--- trunk/Source/WebCore/rendering/InlineFlowBox.cpp	2014-03-01 23:05:02 UTC (rev 164927)
+++ trunk/Source/WebCore/rendering/InlineFlowBox.cpp	2014-03-01 23:22:56 UTC (rev 164928)
@@ -50,13 +50,22 @@
 COMPILE_ASSERT(sizeof(InlineFlowBox) == sizeof(SameSizeAsInlineFlowBox), InlineFlowBox_should_stay_small);
 
 #if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED
+
 InlineFlowBox::~InlineFlowBox()
 {
-    if (!m_hasBadChildList) {
-        for (InlineBox* child = firstChild(); child; child = child->nextOnLine())
-            child->setHasBadParent();
-    }
+    setHasBadChildList();
 }
+
+void InlineFlowBox::setHasBadChildList()
+{
+    assertNotDeleted();
+    if (m_hasBadChildList)
+        return;
+    for (InlineBox* child = firstChild(); child; child = child->nextOnLine())
+        child->setHasBadParent();
+    m_hasBadChildList = true;
+}
+
 #endif
 
 LayoutUnit InlineFlowBox::getFlowSpacingLogicalWidth()
@@ -1664,15 +1673,16 @@
 
 void InlineFlowBox::checkConsistency() const
 {
+    assertNotDeleted();
     ASSERT_WITH_SECURITY_IMPLICATION(!m_hasBadChildList);
 #ifdef CHECK_CONSISTENCY
-    const InlineBox* prev = 0;
-    for (const InlineBox* child = m_firstChild; child; child = child->nextOnLine()) {
+    const InlineBox* previousChild = nullptr;
+    for (const InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
         ASSERT(child->parent() == this);
-        ASSERT(child->prevOnLine() == prev);
-        prev = child;
+        ASSERT(child->prevOnLine() == previousChild);
+        previousChild = child;
     }
-    ASSERT(prev == m_lastChild);
+    ASSERT(previousChild == m_lastChild);
 #endif
 }
 

Modified: trunk/Source/WebCore/rendering/InlineFlowBox.h (164927 => 164928)


--- trunk/Source/WebCore/rendering/InlineFlowBox.h	2014-03-01 23:05:02 UTC (rev 164927)
+++ trunk/Source/WebCore/rendering/InlineFlowBox.h	2014-03-01 23:22:56 UTC (rev 164928)
@@ -352,18 +352,21 @@
 INLINE_BOX_OBJECT_TYPE_CASTS(InlineFlowBox, isInlineFlowBox())
 
 #ifdef NDEBUG
+
 inline void InlineFlowBox::checkConsistency() const
 {
 }
+
 #endif
 
+#if ASSERT_WITH_SECURITY_IMPLICATION_DISABLED
+
 inline void InlineFlowBox::setHasBadChildList()
 {
-#if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED
-    m_hasBadChildList = true;
-#endif
 }
 
+#endif
+
 } // namespace WebCore
 
 #ifndef NDEBUG

Modified: trunk/Source/WebCore/rendering/RenderTextLineBoxes.cpp (164927 => 164928)


--- trunk/Source/WebCore/rendering/RenderTextLineBoxes.cpp	2014-03-01 23:05:02 UTC (rev 164927)
+++ trunk/Source/WebCore/rendering/RenderTextLineBoxes.cpp	2014-03-01 23:22:56 UTC (rev 164928)
@@ -697,10 +697,8 @@
 #if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED
 void RenderTextLineBoxes::invalidateParentChildLists()
 {
-    for (auto box = m_first; box; box = box->nextTextBox()) {
-        if (auto parent = box->parent())
-            parent->setHasBadChildList();
-    }
+    for (auto box = m_first; box; box = box->nextTextBox())
+        box->invalidateParentChildList();
 }
 #endif
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to