Title: [120896] trunk
Revision
120896
Author
[email protected]
Date
2012-06-20 18:34:11 -0700 (Wed, 20 Jun 2012)

Log Message

Source/WebCore: [Shadow][Editing] Deleting character in distributed element caused a crash.
https://bugs.webkit.org/show_bug.cgi?id=88484

Reviewed by Ryosuke Niwa.

If we mutate nodes which are children of a shadow host, it causes
ElementShadow::invalidateDistribution().  As a result, shadow host
is detached (and lazyAttached()) and its renderer is gone.  That
causes assertion error since isEditablePosition() assumes
anchorNode's style was correctly calculated.

This patch makes isEditablePosition() call
document->updateLayoutIgnorePendingStylesheets() so that it does
not return a bogus result.

There is an exceptional caller of isEditablePosition,
RenderBlock::paintCaret(), from where we can not call
updateLayout() in isEditablePosition because it hits assertion,
ASSERT(!isPainting). So I've added the third parameter to
isEditablePosition to control updating the style.

Test: edition/shadow/delete-characters-in-distributed-node.html

* editing/FrameSelection.h:
(WebCore::FrameSelection::rendererIsEditable):
* editing/VisibleSelection.cpp:
(WebCore::VisibleSelection::rendererIsEditable):
(WebCore):
* editing/VisibleSelection.h:
(VisibleSelection):
* editing/htmlediting.cpp:
(WebCore::isEditablePosition):
* editing/htmlediting.h:
(WebCore):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::paintCaret):

LayoutTests: [Shadow][Editing] Deleting character in distributed element caused a crash
https://bugs.webkit.org/show_bug.cgi?id=88484

Reviewed by Ryosuke Niwa.

* editing/shadow/delete-characters-in-distributed-node-crash-expected.txt: Added.
* editing/shadow/delete-characters-in-distributed-node-crash.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (120895 => 120896)


--- trunk/LayoutTests/ChangeLog	2012-06-21 01:31:08 UTC (rev 120895)
+++ trunk/LayoutTests/ChangeLog	2012-06-21 01:34:11 UTC (rev 120896)
@@ -1,3 +1,13 @@
+2012-06-20  Hayato Ito  <[email protected]>
+
+        [Shadow][Editing] Deleting character in distributed element caused a crash
+        https://bugs.webkit.org/show_bug.cgi?id=88484
+
+        Reviewed by Ryosuke Niwa.
+
+        * editing/shadow/delete-characters-in-distributed-node-crash-expected.txt: Added.
+        * editing/shadow/delete-characters-in-distributed-node-crash.html: Added.
+
 2012-06-20  Kent Tamura  <[email protected]>
 
         Unmodified form control value are overwritten by another form

Added: trunk/LayoutTests/editing/shadow/delete-characters-in-distributed-node-crash-expected.txt (0 => 120896)


--- trunk/LayoutTests/editing/shadow/delete-characters-in-distributed-node-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/editing/shadow/delete-characters-in-distributed-node-crash-expected.txt	2012-06-21 01:34:11 UTC (rev 120896)
@@ -0,0 +1,4 @@
+This tests the deletion of text in distributed node does not crash. To run it outside of DRT, you must delete text, 'foo', manually.
+
+
+PASS

Added: trunk/LayoutTests/editing/shadow/delete-characters-in-distributed-node-crash.html (0 => 120896)


--- trunk/LayoutTests/editing/shadow/delete-characters-in-distributed-node-crash.html	                        (rev 0)
+++ trunk/LayoutTests/editing/shadow/delete-characters-in-distributed-node-crash.html	2012-06-21 01:34:11 UTC (rev 120896)
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p id="description">This tests the deletion of text in distributed node does not crash. To run it outside of DRT, you must delete text, 'foo', manually.</p>
+<div id="shadowhost" contenteditable><div>foo</div></div>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+var shadowRoot = new WebKitShadowRoot(document.getElementById('shadowhost'));
+shadowRoot.innerHTML = "<content></content>";
+
+var textNode = document.getElementById('shadowhost').firstChild.firstChild;
+window.getSelection().setBaseAndExtent(textNode, 0, textNode, 3);
+document.execCommand('Delete');
+
+document.write('PASS');
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (120895 => 120896)


--- trunk/Source/WebCore/ChangeLog	2012-06-21 01:31:08 UTC (rev 120895)
+++ trunk/Source/WebCore/ChangeLog	2012-06-21 01:34:11 UTC (rev 120896)
@@ -1,3 +1,42 @@
+2012-06-20  Hayato Ito  <[email protected]>
+
+        [Shadow][Editing] Deleting character in distributed element caused a crash.
+        https://bugs.webkit.org/show_bug.cgi?id=88484
+
+        Reviewed by Ryosuke Niwa.
+
+        If we mutate nodes which are children of a shadow host, it causes
+        ElementShadow::invalidateDistribution().  As a result, shadow host
+        is detached (and lazyAttached()) and its renderer is gone.  That
+        causes assertion error since isEditablePosition() assumes
+        anchorNode's style was correctly calculated.
+
+        This patch makes isEditablePosition() call
+        document->updateLayoutIgnorePendingStylesheets() so that it does
+        not return a bogus result.
+
+        There is an exceptional caller of isEditablePosition,
+        RenderBlock::paintCaret(), from where we can not call
+        updateLayout() in isEditablePosition because it hits assertion,
+        ASSERT(!isPainting). So I've added the third parameter to
+        isEditablePosition to control updating the style.
+
+        Test: edition/shadow/delete-characters-in-distributed-node.html
+
+        * editing/FrameSelection.h:
+        (WebCore::FrameSelection::rendererIsEditable):
+        * editing/VisibleSelection.cpp:
+        (WebCore::VisibleSelection::rendererIsEditable):
+        (WebCore):
+        * editing/VisibleSelection.h:
+        (VisibleSelection):
+        * editing/htmlediting.cpp:
+        (WebCore::isEditablePosition):
+        * editing/htmlediting.h:
+        (WebCore):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::paintCaret):
+
 2012-06-20  Kent Tamura  <[email protected]>
 
         Unmodified form control value are overwritten by another form

Modified: trunk/Source/WebCore/editing/FrameSelection.h (120895 => 120896)


--- trunk/Source/WebCore/editing/FrameSelection.h	2012-06-21 01:31:08 UTC (rev 120895)
+++ trunk/Source/WebCore/editing/FrameSelection.h	2012-06-21 01:34:11 UTC (rev 120896)
@@ -130,6 +130,7 @@
 
     Element* rootEditableElement() const { return m_selection.rootEditableElement(); }
     Element* rootEditableElementOrDocumentElement() const;
+    bool rendererIsEditable() const { return m_selection.rendererIsEditable(); }
     bool isContentEditable() const { return m_selection.isContentEditable(); }
     bool isContentRichlyEditable() const { return m_selection.isContentRichlyEditable(); }
      

Modified: trunk/Source/WebCore/editing/VisibleSelection.cpp (120895 => 120896)


--- trunk/Source/WebCore/editing/VisibleSelection.cpp	2012-06-21 01:31:08 UTC (rev 120895)
+++ trunk/Source/WebCore/editing/VisibleSelection.cpp	2012-06-21 01:34:11 UTC (rev 120896)
@@ -628,6 +628,11 @@
     return isEditablePosition(start());
 }
 
+bool VisibleSelection::rendererIsEditable() const
+{
+    return isEditablePosition(start(), ContentIsEditable, DoNotUpdateStyle);
+}
+
 bool VisibleSelection::isContentRichlyEditable() const
 {
     return isRichlyEditablePosition(start());

Modified: trunk/Source/WebCore/editing/VisibleSelection.h (120895 => 120896)


--- trunk/Source/WebCore/editing/VisibleSelection.h	2012-06-21 01:31:08 UTC (rev 120895)
+++ trunk/Source/WebCore/editing/VisibleSelection.h	2012-06-21 01:34:11 UTC (rev 120896)
@@ -28,6 +28,7 @@
 
 #include "TextGranularity.h"
 #include "VisiblePosition.h"
+#include "htmlediting.h"
 
 namespace WebCore {
 
@@ -99,6 +100,7 @@
     
     Element* rootEditableElement() const;
     bool isContentEditable() const;
+    bool rendererIsEditable() const;
     bool isContentRichlyEditable() const;
     // Returns a shadow tree node for legacy shadow trees, a child of the
     // ShadowRoot node for new shadow trees, or 0 for non-shadow trees.

Modified: trunk/Source/WebCore/editing/htmlediting.cpp (120895 => 120896)


--- trunk/Source/WebCore/editing/htmlediting.cpp	2012-06-21 01:31:08 UTC (rev 120895)
+++ trunk/Source/WebCore/editing/htmlediting.cpp	2012-06-21 01:34:11 UTC (rev 120896)
@@ -145,12 +145,16 @@
     return lowestRoot;
 }
 
-bool isEditablePosition(const Position& p, EditableType editableType)
+bool isEditablePosition(const Position& p, EditableType editableType, EUpdateStyle updateStyle)
 {
     Node* node = p.deprecatedNode();
     if (!node)
         return false;
-        
+    if (updateStyle == UpdateStyle)
+        node->document()->updateLayoutIgnorePendingStylesheets();
+    else
+        ASSERT(updateStyle == DoNotUpdateStyle);
+
     if (node->renderer() && node->renderer()->isTable())
         node = node->parentNode();
     

Modified: trunk/Source/WebCore/editing/htmlediting.h (120895 => 120896)


--- trunk/Source/WebCore/editing/htmlediting.h	2012-06-21 01:31:08 UTC (rev 120895)
+++ trunk/Source/WebCore/editing/htmlediting.h	2012-06-21 01:34:11 UTC (rev 120896)
@@ -151,8 +151,9 @@
 int comparePositions(const Position&, const Position&);
 
 // boolean functions on Position
-    
-bool isEditablePosition(const Position&, EditableType = ContentIsEditable);
+
+enum EUpdateStyle { UpdateStyle, DoNotUpdateStyle };
+bool isEditablePosition(const Position&, EditableType = ContentIsEditable, EUpdateStyle = UpdateStyle);
 bool isRichlyEditablePosition(const Position&, EditableType = ContentIsEditable);
 bool isFirstVisiblePositionInSpecialElement(const Position&);
 bool isLastVisiblePositionInSpecialElement(const Position&);

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (120895 => 120896)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2012-06-21 01:31:08 UTC (rev 120895)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2012-06-21 01:34:11 UTC (rev 120896)
@@ -2885,7 +2885,7 @@
     bool isContentEditable;
     if (type == CursorCaret) {
         caretPainter = frame()->selection()->caretRenderer();
-        isContentEditable = frame()->selection()->isContentEditable();
+        isContentEditable = frame()->selection()->rendererIsEditable();
     } else {
         caretPainter = frame()->page()->dragCaretController()->caretRenderer();
         isContentEditable = frame()->page()->dragCaretController()->isContentEditable();
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to