- Revision
- 105441
- Author
- [email protected]
- Date
- 2012-01-19 13:41:08 -0800 (Thu, 19 Jan 2012)
Log Message
Crash in CompositeEditCommand::ensureComposition
https://bugs.webkit.org/show_bug.cgi?id=76207
Reviewed by Chang Shu.
Source/WebCore:
The crash was caused by TypingCommand not kept alive when new editing commands are executed
during adding more typings to the open last typing command since m_lastEditCommand is replaced
by the new command. Fixed the bug by keeping them alive a little longer with RefPtr.
Test: editing/execCommand/editing-command-while-executing-typing-command-crash.html
* editing/FrameSelection.cpp:
(WebCore::shouldStopBlinkingDueToTypingCommand):
(WebCore::FrameSelection::updateAppearance):
* editing/TypingCommand.cpp:
(WebCore::TypingCommand::deleteSelection):
(WebCore::TypingCommand::deleteKeyPressed):
(WebCore::TypingCommand::forwardDeleteKeyPressed):
(WebCore::TypingCommand::insertText):
(WebCore::TypingCommand::insertLineBreak):
(WebCore::TypingCommand::insertParagraphSeparatorInQuotedContent):
(WebCore::TypingCommand::insertParagraphSeparator):
(WebCore::TypingCommand::lastTypingCommandIfStillOpenForTyping):
(WebCore::TypingCommand::closeTyping):
* editing/TypingCommand.h:
LayoutTests:
Add a regression test.
* editing/execCommand/editing-command-while-executing-typing-command-crash-expected.txt: Added.
* editing/execCommand/editing-command-while-executing-typing-command-crash.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (105440 => 105441)
--- trunk/LayoutTests/ChangeLog 2012-01-19 21:16:46 UTC (rev 105440)
+++ trunk/LayoutTests/ChangeLog 2012-01-19 21:41:08 UTC (rev 105441)
@@ -1,3 +1,15 @@
+2012-01-13 Ryosuke Niwa <[email protected]>
+
+ Crash in CompositeEditCommand::ensureComposition
+ https://bugs.webkit.org/show_bug.cgi?id=76207
+
+ Reviewed by Chang Shu.
+
+ Add a regression test.
+
+ * editing/execCommand/editing-command-while-executing-typing-command-crash-expected.txt: Added.
+ * editing/execCommand/editing-command-while-executing-typing-command-crash.html: Added.
+
2012-01-19 Eric Carlson <[email protected]>
https://bugs.webkit.org/show_bug.cgi?id=75192
Added: trunk/LayoutTests/editing/execCommand/editing-command-while-executing-typing-command-crash-expected.txt (0 => 105441)
--- trunk/LayoutTests/editing/execCommand/editing-command-while-executing-typing-command-crash-expected.txt (rev 0)
+++ trunk/LayoutTests/editing/execCommand/editing-command-while-executing-typing-command-crash-expected.txt 2012-01-19 21:41:08 UTC (rev 105441)
@@ -0,0 +1,2 @@
+This tests executing an editing command while executing a typing command.
+PASS
Added: trunk/LayoutTests/editing/execCommand/editing-command-while-executing-typing-command-crash.html (0 => 105441)
--- trunk/LayoutTests/editing/execCommand/editing-command-while-executing-typing-command-crash.html (rev 0)
+++ trunk/LayoutTests/editing/execCommand/editing-command-while-executing-typing-command-crash.html 2012-01-19 21:41:08 UTC (rev 105441)
@@ -0,0 +1,18 @@
+<script>
+window._onload_ = function() {
+ if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+ document.execCommand("selectall", false);
+ document.designMode="on";
+ document.execCommand("insertparagraph", false);
+ document.execCommand("InsertText", false);
+
+ document.firstChild.appendChild(document.createElement('body'));
+ document.body.innerText = "This tests executing an editing command while executing a typing command.\nPASS";
+};
+
+document.addEventListener("DOMNodeRemovedFromDocument",
+ function() { document.execCommand("JustifyNone", false); },true);
+
+</script>
Modified: trunk/Source/WebCore/ChangeLog (105440 => 105441)
--- trunk/Source/WebCore/ChangeLog 2012-01-19 21:16:46 UTC (rev 105440)
+++ trunk/Source/WebCore/ChangeLog 2012-01-19 21:41:08 UTC (rev 105441)
@@ -1,3 +1,31 @@
+2012-01-13 Ryosuke Niwa <[email protected]>
+
+ Crash in CompositeEditCommand::ensureComposition
+ https://bugs.webkit.org/show_bug.cgi?id=76207
+
+ Reviewed by Chang Shu.
+
+ The crash was caused by TypingCommand not kept alive when new editing commands are executed
+ during adding more typings to the open last typing command since m_lastEditCommand is replaced
+ by the new command. Fixed the bug by keeping them alive a little longer with RefPtr.
+
+ Test: editing/execCommand/editing-command-while-executing-typing-command-crash.html
+
+ * editing/FrameSelection.cpp:
+ (WebCore::shouldStopBlinkingDueToTypingCommand):
+ (WebCore::FrameSelection::updateAppearance):
+ * editing/TypingCommand.cpp:
+ (WebCore::TypingCommand::deleteSelection):
+ (WebCore::TypingCommand::deleteKeyPressed):
+ (WebCore::TypingCommand::forwardDeleteKeyPressed):
+ (WebCore::TypingCommand::insertText):
+ (WebCore::TypingCommand::insertLineBreak):
+ (WebCore::TypingCommand::insertParagraphSeparatorInQuotedContent):
+ (WebCore::TypingCommand::insertParagraphSeparator):
+ (WebCore::TypingCommand::lastTypingCommandIfStillOpenForTyping):
+ (WebCore::TypingCommand::closeTyping):
+ * editing/TypingCommand.h:
+
2012-01-19 Andreas Kling <[email protected]>
Unreviewed debug build fix.
Modified: trunk/Source/WebCore/editing/FrameSelection.cpp (105440 => 105441)
--- trunk/Source/WebCore/editing/FrameSelection.cpp 2012-01-19 21:16:46 UTC (rev 105440)
+++ trunk/Source/WebCore/editing/FrameSelection.cpp 2012-01-19 21:41:08 UTC (rev 105441)
@@ -1654,6 +1654,11 @@
return m_focused && m_frame->page() && m_frame->page()->focusController()->isActive();
}
+inline static bool shouldStopBlinkingDueToTypingCommand(Frame* frame)
+{
+ return frame->editor()->lastEditCommand() && frame->editor()->lastEditCommand()->shouldStopCaretBlinking();
+}
+
void FrameSelection::updateAppearance()
{
#if ENABLE(TEXT_CARET)
@@ -1661,13 +1666,10 @@
bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBrowsingEnabled();
bool shouldBlink = caretIsVisible() && isCaret() && (isContentEditable() || caretBrowsing);
-
- CompositeEditCommand* lastEditCommand = m_frame ? m_frame->editor()->lastEditCommand() : 0;
- bool shouldStopBlinkingDueToTypingCommand = lastEditCommand && lastEditCommand->shouldStopCaretBlinking();
// If the caret moved, stop the blink timer so we can restart with a
// black caret in the new location.
- if (caretRectChanged || !shouldBlink || shouldStopBlinkingDueToTypingCommand)
+ if (caretRectChanged || !shouldBlink || shouldStopBlinkingDueToTypingCommand(m_frame))
m_caretBlinkTimer.stop();
// Start blinking with a black caret. Be sure not to restart if we're
Modified: trunk/Source/WebCore/editing/TypingCommand.cpp (105440 => 105441)
--- trunk/Source/WebCore/editing/TypingCommand.cpp 2012-01-19 21:16:46 UTC (rev 105440)
+++ trunk/Source/WebCore/editing/TypingCommand.cpp 2012-01-19 21:41:08 UTC (rev 105441)
@@ -87,7 +87,7 @@
if (!frame->selection()->isRange())
return;
- if (TypingCommand* lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame)) {
+ if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame)) {
lastTypingCommand->setShouldPreventSpellChecking(options & PreventSpellChecking);
lastTypingCommand->deleteSelection(options & SmartDelete);
return;
@@ -100,8 +100,8 @@
{
ASSERT(document);
if (granularity == CharacterGranularity) {
- if (TypingCommand* lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame())) {
- updateSelectionIfDifferentFromCurrentSelection(lastTypingCommand, document->frame());
+ if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame())) {
+ updateSelectionIfDifferentFromCurrentSelection(lastTypingCommand.get(), document->frame());
lastTypingCommand->setShouldPreventSpellChecking(options & PreventSpellChecking);
lastTypingCommand->deleteKeyPressed(granularity, options & KillRing);
return;
@@ -117,8 +117,8 @@
ASSERT(document);
Frame* frame = document->frame();
if (granularity == CharacterGranularity) {
- if (TypingCommand* lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame)) {
- updateSelectionIfDifferentFromCurrentSelection(lastTypingCommand, frame);
+ if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame)) {
+ updateSelectionIfDifferentFromCurrentSelection(lastTypingCommand.get(), frame);
lastTypingCommand->setShouldPreventSpellChecking(options & PreventSpellChecking);
lastTypingCommand->forwardDeleteKeyPressed(granularity, options & KillRing);
return;
@@ -176,7 +176,7 @@
// Set the starting and ending selection appropriately if we are using a selection
// that is different from the current selection. In the future, we should change EditCommand
// to deal with custom selections in a general way that can be used by all of the commands.
- if (TypingCommand* lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame.get())) {
+ if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame.get())) {
if (lastTypingCommand->endingSelection() != selectionForInsertion) {
lastTypingCommand->setStartingSelection(selectionForInsertion);
lastTypingCommand->setEndingSelection(selectionForInsertion);
@@ -204,7 +204,7 @@
void TypingCommand::insertLineBreak(Document *document, Options options)
{
ASSERT(document);
- if (TypingCommand* lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame())) {
+ if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame())) {
lastTypingCommand->setShouldRetainAutocorrectionIndicator(options & RetainAutocorrectionIndicator);
lastTypingCommand->insertLineBreak();
return;
@@ -216,7 +216,7 @@
void TypingCommand::insertParagraphSeparatorInQuotedContent(Document *document)
{
ASSERT(document);
- if (TypingCommand* lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame())) {
+ if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame())) {
lastTypingCommand->insertParagraphSeparatorInQuotedContent();
return;
}
@@ -227,7 +227,7 @@
void TypingCommand::insertParagraphSeparator(Document *document, Options options)
{
ASSERT(document);
- if (TypingCommand* lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame())) {
+ if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document->frame())) {
lastTypingCommand->setShouldRetainAutocorrectionIndicator(options & RetainAutocorrectionIndicator);
lastTypingCommand->insertParagraphSeparator();
return;
@@ -236,20 +236,20 @@
applyCommand(TypingCommand::create(document, InsertParagraphSeparator, "", options));
}
-TypingCommand* TypingCommand::lastTypingCommandIfStillOpenForTyping(Frame* frame)
+PassRefPtr<TypingCommand> TypingCommand::lastTypingCommandIfStillOpenForTyping(Frame* frame)
{
ASSERT(frame);
- CompositeEditCommand* lastEditCommand = frame->editor()->lastEditCommand();
- if (!lastEditCommand || !lastEditCommand->isTypingCommand() || !static_cast<TypingCommand*>(lastEditCommand)->isOpenForMoreTyping())
+ RefPtr<CompositeEditCommand> lastEditCommand = frame->editor()->lastEditCommand();
+ if (!lastEditCommand || !lastEditCommand->isTypingCommand() || !static_cast<TypingCommand*>(lastEditCommand.get())->isOpenForMoreTyping())
return 0;
- return static_cast<TypingCommand*>(lastEditCommand);
+ return static_cast<TypingCommand*>(lastEditCommand.get());
}
void TypingCommand::closeTyping(Frame* frame)
{
- if (TypingCommand* lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame))
+ if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame))
lastTypingCommand->closeTyping();
}
Modified: trunk/Source/WebCore/editing/TypingCommand.h (105440 => 105441)
--- trunk/Source/WebCore/editing/TypingCommand.h 2012-01-19 21:16:46 UTC (rev 105440)
+++ trunk/Source/WebCore/editing/TypingCommand.h 2012-01-19 21:41:08 UTC (rev 105441)
@@ -95,7 +95,7 @@
bool isOpenForMoreTyping() const { return m_openForMoreTyping; }
void closeTyping() { m_openForMoreTyping = false; }
- static TypingCommand* lastTypingCommandIfStillOpenForTyping(Frame*);
+ static PassRefPtr<TypingCommand> lastTypingCommandIfStillOpenForTyping(Frame*);
virtual void doApply();
virtual EditAction editingAction() const;