Title: [204620] trunk/Source/WebCore
Revision
204620
Author
[email protected]
Date
2016-08-18 18:01:47 -0700 (Thu, 18 Aug 2016)

Log Message

Binding NULL pointer to reference in WebCore::RenderObject
https://bugs.webkit.org/show_bug.cgi?id=160830

Patch by Jonathan Bedard <[email protected]> on 2016-08-18
Reviewed by Myles C. Maxfield.

No new tests needed, existing functionality not changed.

Fixes a dereferenced NULL pointer bound to a reference through a minor re-factor.

* rendering/InlineIterator.h:
(WebCore::InlineIterator::clear): Explicit clear occurs, instead of a call to moveTo.
(WebCore::InlineIterator::moveToStartOf): Swapped pointer for reference.
(WebCore::InlineIterator::moveTo): Swapped pointer for reference.
(WebCore::InlineIterator::increment): Explicitly call clear for clarity.
* rendering/line/BreakingContext.h:
(WebCore::BreakingContext::commitLineBreakClear): Commit a line break and clear the iterator.
(WebCore::BreakingContext::commitLineBreakAtCurrentWidth): Swapped pointer for reference.
(WebCore::BreakingContext::InlineIteratorHistory::moveTo): Swapped pointer for reference.
(WebCore::BreakingContext::increment): Explicitly call clear for clarity.
(WebCore::BreakingContext::handleBR): Swapped pointer for passed reference.
(WebCore::BreakingContext::handleReplaced): Explicitly call clear for clarity.
(WebCore::tryHyphenating): Swapped pointer for passed reference.
(WebCore::BreakingContext::handleText): Replaced all render object passing with references.  Note that the caller explicitly checks if m_current.renderer() exists before calling this function.
(WebCore::BreakingContext::commitAndUpdateLineBreakIfNeeded): Explicitly call clear for clarity.
(WebCore::BreakingContext::handleEndOfLine): Explicitly call clear for clarity.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (204619 => 204620)


--- trunk/Source/WebCore/ChangeLog	2016-08-19 00:55:42 UTC (rev 204619)
+++ trunk/Source/WebCore/ChangeLog	2016-08-19 01:01:47 UTC (rev 204620)
@@ -1,3 +1,31 @@
+2016-08-18  Jonathan Bedard  <[email protected]>
+
+        Binding NULL pointer to reference in WebCore::RenderObject
+        https://bugs.webkit.org/show_bug.cgi?id=160830
+
+        Reviewed by Myles C. Maxfield.
+
+        No new tests needed, existing functionality not changed.
+
+        Fixes a dereferenced NULL pointer bound to a reference through a minor re-factor.
+
+        * rendering/InlineIterator.h:
+        (WebCore::InlineIterator::clear): Explicit clear occurs, instead of a call to moveTo.
+        (WebCore::InlineIterator::moveToStartOf): Swapped pointer for reference.
+        (WebCore::InlineIterator::moveTo): Swapped pointer for reference.
+        (WebCore::InlineIterator::increment): Explicitly call clear for clarity.
+        * rendering/line/BreakingContext.h:
+        (WebCore::BreakingContext::commitLineBreakClear): Commit a line break and clear the iterator.
+        (WebCore::BreakingContext::commitLineBreakAtCurrentWidth): Swapped pointer for reference.
+        (WebCore::BreakingContext::InlineIteratorHistory::moveTo): Swapped pointer for reference.
+        (WebCore::BreakingContext::increment): Explicitly call clear for clarity.
+        (WebCore::BreakingContext::handleBR): Swapped pointer for passed reference.
+        (WebCore::BreakingContext::handleReplaced): Explicitly call clear for clarity.
+        (WebCore::tryHyphenating): Swapped pointer for passed reference.
+        (WebCore::BreakingContext::handleText): Replaced all render object passing with references.  Note that the caller explicitly checks if m_current.renderer() exists before calling this function.
+        (WebCore::BreakingContext::commitAndUpdateLineBreakIfNeeded): Explicitly call clear for clarity.
+        (WebCore::BreakingContext::handleEndOfLine): Explicitly call clear for clarity.
+
 2016-08-18  Ryosuke Niwa  <[email protected]>
 
         Windows build fix after r204611. Use the fully qualified name to avoid the ambiguity in VC++.

Modified: trunk/Source/WebCore/rendering/InlineIterator.h (204619 => 204620)


--- trunk/Source/WebCore/rendering/InlineIterator.h	2016-08-19 00:55:42 UTC (rev 204619)
+++ trunk/Source/WebCore/rendering/InlineIterator.h	2016-08-19 01:01:47 UTC (rev 204620)
@@ -64,16 +64,20 @@
     {
     }
 
-    void clear() { moveTo(nullptr, 0); }
-
-    void moveToStartOf(RenderObject* object)
+    void clear()
     {
+        setRenderer(nullptr);
+        setOffset(0);
+        setNextBreakablePosition(-1);
+    }
+    void moveToStartOf(RenderObject& object)
+    {
         moveTo(object, 0);
     }
 
-    void moveTo(RenderObject* object, unsigned offset, Optional<unsigned> nextBreak = Nullopt)
+    void moveTo(RenderObject& object, unsigned offset, Optional<unsigned> nextBreak = Optional<unsigned>())
     {
-        setRenderer(object);
+        setRenderer(&object);
         setOffset(offset);
         setNextBreakablePosition(nextBreak);
     }
@@ -397,8 +401,12 @@
         if (m_pos < downcast<RenderText>(*m_renderer).textLength())
             return;
     }
-    // bidiNext can return nullptr, so use moveTo instead of moveToStartOf
-    moveTo(bidiNextSkippingEmptyInlines(*m_root, m_renderer, resolver), 0);
+    // bidiNext can return nullptr
+    RenderObject* bidiNext = bidiNextSkippingEmptyInlines(*m_root, m_renderer, resolver);
+    if (bidiNext)
+        moveToStartOf(*bidiNext);
+    else
+        clear();
 }
 
 inline void InlineIterator::fastDecrement()

Modified: trunk/Source/WebCore/rendering/line/BreakingContext.h (204619 => 204620)


--- trunk/Source/WebCore/rendering/line/BreakingContext.h	2016-08-19 00:55:42 UTC (rev 204619)
+++ trunk/Source/WebCore/rendering/line/BreakingContext.h	2016-08-19 01:01:47 UTC (rev 204620)
@@ -166,13 +166,20 @@
         m_hangsAtEnd = false;
     }
 
-    void commitLineBreakAtCurrentWidth(RenderObject& object, unsigned offset = 0, Optional<unsigned> nextBreak = Nullopt)
+    void commitLineBreakClear()
     {
         m_width.commit();
-        m_lineBreakHistory.moveTo(&object, offset, nextBreak);
+        m_lineBreakHistory.clear();
         m_hangsAtEnd = false;
     }
 
+    void commitLineBreakAtCurrentWidth(RenderObject& object, unsigned offset = 0, Optional<unsigned> nextBreak = Optional<unsigned>())
+    {
+        m_width.commit();
+        m_lineBreakHistory.moveTo(object, offset, nextBreak);
+        m_hangsAtEnd = false;
+    }
+
 private:
     // This class keeps a sliding window of the past n locations for an InlineIterator.
     class InlineIteratorHistory : private Vector<InlineIterator, 1> {
@@ -210,7 +217,7 @@
         const InlineIterator& current() const { return get(0); }
         size_t historyLength() const { return this->size(); }
 
-        void moveTo(RenderObject* object, unsigned offset, Optional<unsigned> nextBreak = Nullopt)
+        void moveTo(RenderObject& object, unsigned offset, Optional<unsigned> nextBreak = Nullopt)
         {
             push([&](InlineIterator& modifyMe) {
                 modifyMe.moveTo(object, offset, nextBreak);
@@ -326,7 +333,10 @@
     if (!m_collapseWhiteSpace)
         m_currentCharacterIsSpace = false;
 
-    m_current.moveToStartOf(m_nextObject);
+    if (m_nextObject)
+        m_current.moveToStartOf(*m_nextObject);
+    else
+        m_current.clear();
     m_atStart = false;
 }
 
@@ -335,7 +345,7 @@
     if (fitsOnLineOrHangsAtEnd()) {
         RenderObject& br = *m_current.renderer();
         m_lineBreakHistory.push([&](InlineIterator& modifyMe) {
-            modifyMe.moveToStartOf(&br);
+            modifyMe.moveToStartOf(br);
             modifyMe.increment();
         });
 
@@ -533,7 +543,10 @@
     // Break on replaced elements if either has normal white-space.
     if (((m_autoWrap || RenderStyle::autoWrap(m_lastWS)) && (!m_current.renderer()->isImage() || m_allowImagesToBreak)
         && (!m_current.renderer()->isRubyRun() || downcast<RenderRubyRun>(m_current.renderer())->canBreakBefore(m_renderTextInfo.lineBreakIterator))) || replacedBox.isAnonymousInlineBlock()) {
-        commitLineBreakAtCurrentWidth(*m_current.renderer());
+        if (auto* renderer = m_current.renderer())
+            commitLineBreakAtCurrentWidth(*renderer);
+        else
+            commitLineBreakClear();
         if (m_width.committedWidth() && replacedBox.isAnonymousInlineBlock()) {
             // Always force a break before an anonymous inline block if there is content on the line
             // already.
@@ -713,7 +726,7 @@
     UNUSED_PARAM(isFixedPitch);
 #endif
 
-    lineBreak.moveTo(&text, lastSpace + prefixLength, nextBreakable);
+    lineBreak.moveTo(text, lastSpace + prefixLength, nextBreakable);
     hyphenated = true;
 }
 
@@ -749,7 +762,8 @@
     if (!m_current.offset())
         m_appliedStartWidth = false;
 
-    RenderText& renderText = downcast<RenderText>(*m_current.renderer());
+    RenderObject& renderObject = *m_current.renderer();
+    RenderText& renderText = downcast<RenderText>(renderObject);
 
     bool isSVGText = renderText.isSVGInlineText();
 
@@ -931,7 +945,7 @@
                     if (!m_width.fitsOnLineIncludingExtraWidth(charWidth)) {
                         lineWasTooWide = true;
                         m_lineBreakHistory.push([&](InlineIterator& modifyMe) {
-                            modifyMe.moveTo(m_current.renderer(), m_current.offset(), m_current.nextBreakablePosition());
+                            modifyMe.moveTo(renderObject, m_current.offset(), m_current.nextBreakablePosition());
                             m_lineBreaker.skipTrailingWhitespace(modifyMe, m_lineInfo);
                         });
                     }
@@ -1008,7 +1022,7 @@
             if (c == '\n' && m_preservesNewline) {
                 if (!stoppedIgnoringSpaces && m_current.offset())
                     ensureCharacterGetsLineBox(m_lineWhitespaceCollapsingState, m_current);
-                commitLineBreakAtCurrentWidth(*m_current.renderer(), m_current.offset(), m_current.nextBreakablePosition());
+                commitLineBreakAtCurrentWidth(renderObject, m_current.offset(), m_current.nextBreakablePosition());
                 m_lineBreakHistory.increment();
                 m_lineInfo.setPreviousLineBrokeCleanly(true);
                 return true;
@@ -1015,7 +1029,7 @@
             }
 
             if (m_autoWrap && betweenWords) {
-                commitLineBreakAtCurrentWidth(*m_current.renderer(), m_current.offset(), m_current.nextBreakablePosition());
+                commitLineBreakAtCurrentWidth(renderObject, m_current.offset(), m_current.nextBreakablePosition());
                 wrapW = 0;
                 // Auto-wrapping text should not wrap in the middle of a word once it has had an
                 // opportunity to break after a word.
@@ -1025,7 +1039,7 @@
             if (midWordBreak && !U16_IS_TRAIL(c) && !(U_GET_GC_MASK(c) & U_GC_M_MASK)) {
                 // Remember this as a breakable position in case
                 // adding the end width forces a break.
-                m_lineBreakHistory.moveTo(m_current.renderer(), m_current.offset(), m_current.nextBreakablePosition());
+                m_lineBreakHistory.moveTo(renderObject, m_current.offset(), m_current.nextBreakablePosition());
                 midWordBreak &= (breakWords || breakAll);
             }
 
@@ -1085,7 +1099,7 @@
 
         if (!m_currentCharacterIsWS && previousCharacterIsWS) {
             if (m_autoWrap && m_currentStyle->breakOnlyAfterWhiteSpace())
-                m_lineBreakHistory.moveTo(m_current.renderer(), m_current.offset(), m_current.nextBreakablePosition());
+                m_lineBreakHistory.moveTo(renderObject, m_current.offset(), m_current.nextBreakablePosition());
         }
 
         if (m_collapseWhiteSpace && m_currentCharacterIsSpace && !m_ignoringSpaces)
@@ -1223,8 +1237,12 @@
 
     if (!m_current.renderer()->isFloatingOrOutOfFlowPositioned()) {
         m_lastObject = m_current.renderer();
-        if (m_lastObject->isReplaced() && m_autoWrap && !m_lastObject->isRubyRun() && (!m_lastObject->isImage() || m_allowImagesToBreak) && (!is<RenderListMarker>(*m_lastObject) || downcast<RenderListMarker>(*m_lastObject).isInside()))
-            commitLineBreakAtCurrentWidth(*m_nextObject);
+        if (m_lastObject->isReplaced() && m_autoWrap && !m_lastObject->isRubyRun() && (!m_lastObject->isImage() || m_allowImagesToBreak) && (!is<RenderListMarker>(*m_lastObject) || downcast<RenderListMarker>(*m_lastObject).isInside())) {
+            if (m_nextObject)
+                commitLineBreakAtCurrentWidth(*m_nextObject);
+            else
+                commitLineBreakClear();
+        }
     }
 }
 
@@ -1257,8 +1275,12 @@
     if (m_lineBreakHistory.current() == m_resolver.position()) {
         if (!m_lineBreakHistory.renderer() || !m_lineBreakHistory.renderer()->isBR()) {
             // we just add as much as possible
-            if (m_blockStyle.whiteSpace() == PRE && !m_current.offset())
-                commitLineBreakAtCurrentWidth(*m_lastObject, m_lastObject->isText() ? m_lastObject->length() : 0);
+            if (m_blockStyle.whiteSpace() == PRE && !m_current.offset()) {
+                if (m_lastObject)
+                    commitLineBreakAtCurrentWidth(*m_lastObject, m_lastObject->isText() ? m_lastObject->length() : 0);
+                else
+                    commitLineBreakClear();
+            }
             else if (m_lineBreakHistory.renderer()) {
                 // 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,
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to