Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(517)

Side by Side Diff: Source/core/editing/CompositeEditCommand.cpp

Issue 141103006: Protect document.execCommand() from recursive call and DOM mutation events (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« Source/core/dom/Document.cpp ('K') | « Source/core/dom/Document.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 15 matching lines...) Expand all
26 #include "config.h" 26 #include "config.h"
27 #include "core/editing/CompositeEditCommand.h" 27 #include "core/editing/CompositeEditCommand.h"
28 28
29 #include "HTMLNames.h" 29 #include "HTMLNames.h"
30 #include "bindings/v8/ExceptionStatePlaceholder.h" 30 #include "bindings/v8/ExceptionStatePlaceholder.h"
31 #include "core/dom/Document.h" 31 #include "core/dom/Document.h"
32 #include "core/dom/DocumentFragment.h" 32 #include "core/dom/DocumentFragment.h"
33 #include "core/dom/DocumentMarkerController.h" 33 #include "core/dom/DocumentMarkerController.h"
34 #include "core/dom/NodeTraversal.h" 34 #include "core/dom/NodeTraversal.h"
35 #include "core/dom/Range.h" 35 #include "core/dom/Range.h"
36 #include "core/events/ScopedEventQueue.h"
37 #include "core/dom/Text.h" 36 #include "core/dom/Text.h"
38 #include "core/editing/AppendNodeCommand.h" 37 #include "core/editing/AppendNodeCommand.h"
39 #include "core/editing/ApplyStyleCommand.h" 38 #include "core/editing/ApplyStyleCommand.h"
40 #include "core/editing/DeleteFromTextNodeCommand.h" 39 #include "core/editing/DeleteFromTextNodeCommand.h"
41 #include "core/editing/DeleteSelectionCommand.h" 40 #include "core/editing/DeleteSelectionCommand.h"
42 #include "core/editing/Editor.h" 41 #include "core/editing/Editor.h"
43 #include "core/editing/InsertIntoTextNodeCommand.h" 42 #include "core/editing/InsertIntoTextNodeCommand.h"
44 #include "core/editing/InsertLineBreakCommand.h" 43 #include "core/editing/InsertLineBreakCommand.h"
45 #include "core/editing/InsertNodeBeforeCommand.h" 44 #include "core/editing/InsertNodeBeforeCommand.h"
46 #include "core/editing/InsertParagraphSeparatorCommand.h" 45 #include "core/editing/InsertParagraphSeparatorCommand.h"
(...skipping 19 matching lines...) Expand all
66 #include "core/rendering/InlineTextBox.h" 65 #include "core/rendering/InlineTextBox.h"
67 #include "core/rendering/RenderBlock.h" 66 #include "core/rendering/RenderBlock.h"
68 #include "core/rendering/RenderText.h" 67 #include "core/rendering/RenderText.h"
69 68
70 using namespace std; 69 using namespace std;
71 70
72 namespace WebCore { 71 namespace WebCore {
73 72
74 using namespace HTMLNames; 73 using namespace HTMLNames;
75 74
76 namespace {
77 class ReentrancyGuard {
78 public:
79 static bool isRecursiveCall() { return s_nestingCounter; }
80
81 class Scope {
82 public:
83 Scope() { ++s_nestingCounter; }
84 ~Scope() { --s_nestingCounter; }
85 };
86 friend class Scope;
87
88 private:
89 static int s_nestingCounter;
90 };
91 int ReentrancyGuard::s_nestingCounter;
92 }
93
94 PassRefPtr<EditCommandComposition> EditCommandComposition::create(Document* docu ment, 75 PassRefPtr<EditCommandComposition> EditCommandComposition::create(Document* docu ment,
95 const VisibleSelection& startingSelection, const VisibleSelection& endingSel ection, EditAction editAction) 76 const VisibleSelection& startingSelection, const VisibleSelection& endingSel ection, EditAction editAction)
96 { 77 {
97 return adoptRef(new EditCommandComposition(document, startingSelection, endi ngSelection, editAction)); 78 return adoptRef(new EditCommandComposition(document, startingSelection, endi ngSelection, editAction));
98 } 79 }
99 80
100 EditCommandComposition::EditCommandComposition(Document* document, const Visible Selection& startingSelection, const VisibleSelection& endingSelection, EditActio n editAction) 81 EditCommandComposition::EditCommandComposition(Document* document, const Visible Selection& startingSelection, const VisibleSelection& endingSelection, EditActio n editAction)
101 : m_document(document) 82 : m_document(document)
102 , m_startingSelection(startingSelection) 83 , m_startingSelection(startingSelection)
103 , m_endingSelection(endingSelection) 84 , m_endingSelection(endingSelection)
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 { 156 {
176 } 157 }
177 158
178 CompositeEditCommand::~CompositeEditCommand() 159 CompositeEditCommand::~CompositeEditCommand()
179 { 160 {
180 ASSERT(isTopLevelCommand() || !m_composition); 161 ASSERT(isTopLevelCommand() || !m_composition);
181 } 162 }
182 163
183 void CompositeEditCommand::apply() 164 void CompositeEditCommand::apply()
184 { 165 {
185 // We don't allow recusrive |apply()| to protect against attack code.
186 // Recursive call of |apply()| could be happened by moving iframe
187 // with script triggered by insertion, e.g. <iframe src="javascript:...">
188 // <iframe onload="...">. This usage is valid as of the specification
189 // although, it isn't common use case, rather it is used as attack code.
190 if (ReentrancyGuard::isRecursiveCall())
191 return;
192
193 if (!endingSelection().isContentRichlyEditable()) { 166 if (!endingSelection().isContentRichlyEditable()) {
194 switch (editingAction()) { 167 switch (editingAction()) {
195 case EditActionTyping: 168 case EditActionTyping:
196 case EditActionPaste: 169 case EditActionPaste:
197 case EditActionDrag: 170 case EditActionDrag:
198 case EditActionSetWritingDirection: 171 case EditActionSetWritingDirection:
199 case EditActionCut: 172 case EditActionCut:
200 case EditActionUnspecified: 173 case EditActionUnspecified:
201 break; 174 break;
202 default: 175 default:
203 ASSERT_NOT_REACHED(); 176 ASSERT_NOT_REACHED();
204 return; 177 return;
205 } 178 }
206 } 179 }
207 ensureComposition(); 180 ensureComposition();
208 181
209 // Changes to the document may have been made since the last editing operati on that require a layout, as in <rdar://problem/5658603>. 182 // Changes to the document may have been made since the last editing operati on that require a layout, as in <rdar://problem/5658603>.
210 // Low level operations, like RemoveNodeCommand, don't require a layout beca use the high level operations that use them perform one 183 // Low level operations, like RemoveNodeCommand, don't require a layout beca use the high level operations that use them perform one
211 // if one is necessary (like for the creation of VisiblePositions). 184 // if one is necessary (like for the creation of VisiblePositions).
212 document().updateLayoutIgnorePendingStylesheets(); 185 document().updateLayoutIgnorePendingStylesheets();
213 186
214 Frame* frame = document().frame(); 187 Frame* frame = document().frame();
215 ASSERT(frame); 188 ASSERT(frame);
216 { 189 doApply();
217 EventQueueScope eventQueueScope;
218 ReentrancyGuard::Scope reentrancyGuardScope;
219 doApply();
220 }
221 190
222 // Only need to call appliedEditing for top-level commands, 191 // Only need to call appliedEditing for top-level commands,
223 // and TypingCommands do it on their own (see TypingCommand::typingAddedToOp enCommand). 192 // and TypingCommands do it on their own (see TypingCommand::typingAddedToOp enCommand).
224 if (!isTypingCommand()) 193 if (!isTypingCommand())
225 frame->editor().appliedEditing(this); 194 frame->editor().appliedEditing(this);
226 setShouldRetainAutocorrectionIndicator(false); 195 setShouldRetainAutocorrectionIndicator(false);
227 } 196 }
228 197
229 EditCommandComposition* CompositeEditCommand::ensureComposition() 198 EditCommandComposition* CompositeEditCommand::ensureComposition()
230 { 199 {
(...skipping 1249 matching lines...) Expand 10 before | Expand all | Expand 10 after
1480 return node.release(); 1449 return node.release();
1481 } 1450 }
1482 1451
1483 PassRefPtr<Element> createBlockPlaceholderElement(Document& document) 1452 PassRefPtr<Element> createBlockPlaceholderElement(Document& document)
1484 { 1453 {
1485 RefPtr<Element> breakNode = document.createElement(brTag, false); 1454 RefPtr<Element> breakNode = document.createElement(brTag, false);
1486 return breakNode.release(); 1455 return breakNode.release();
1487 } 1456 }
1488 1457
1489 } // namespace WebCore 1458 } // namespace WebCore
OLDNEW
« Source/core/dom/Document.cpp ('K') | « Source/core/dom/Document.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698