Title: [189306] branches/safari-601-branch
- Revision
- 189306
- Author
- [email protected]
- Date
- 2015-09-03 16:03:59 -0700 (Thu, 03 Sep 2015)
Log Message
Merged r186984. rdar://problem/22316497
Modified Paths
Added Paths
Diff
Modified: branches/safari-601-branch/LayoutTests/ChangeLog (189305 => 189306)
--- branches/safari-601-branch/LayoutTests/ChangeLog 2015-09-03 22:53:51 UTC (rev 189305)
+++ branches/safari-601-branch/LayoutTests/ChangeLog 2015-09-03 23:03:59 UTC (rev 189306)
@@ -1,3 +1,24 @@
+2015-09-03 Babak Shafiei <[email protected]>
+
+ Merge r186984.
+
+ 2015-07-17 Zalan Bujtas <[email protected]>
+
+ REGRESSION (r169105): Do not assign a renderer to multiple selection subtrees.
+ https://bugs.webkit.org/show_bug.cgi?id=147038
+ rdar://problem/21819351
+
+ Reviewed by David Kilzer.
+
+ A renderer should never be assigned to multiple selection subtrees. (Currently RenderObject maintains the last selection state.)
+ RenderView::applySubtreeSelection() loops from the start to the end of the selection to find renderers that are inside the selection.
+ However, in case of regions (when multiple selection roots are present) traversing the renderer tree by calling RenderObject::nextInPreOrder() could
+ end up going across selection roots.
+ This patch ensures that we assign renderers to a specific selection only when the current selection root and the renderer's selection root match.
+
+ * fast/regions/crash-when-renderer-is-in-multiple-selection-subtrees2-expected.txt: Added.
+ * fast/regions/crash-when-renderer-is-in-multiple-selection-subtrees2.html: Added.
+
2015-08-28 Babak Shafiei <[email protected]>
Merge r189024.
Copied: branches/safari-601-branch/LayoutTests/fast/regions/crash-when-renderer-is-in-multiple-selection-subtrees2-expected.txt (from rev 186984, trunk/LayoutTests/fast/regions/crash-when-renderer-is-in-multiple-selection-subtrees2-expected.txt) (0 => 189306)
--- branches/safari-601-branch/LayoutTests/fast/regions/crash-when-renderer-is-in-multiple-selection-subtrees2-expected.txt (rev 0)
+++ branches/safari-601-branch/LayoutTests/fast/regions/crash-when-renderer-is-in-multiple-selection-subtrees2-expected.txt 2015-09-03 23:03:59 UTC (rev 189306)
@@ -0,0 +1,3 @@
+PASS if no assert or crash.
+
+foobar
Copied: branches/safari-601-branch/LayoutTests/fast/regions/crash-when-renderer-is-in-multiple-selection-subtrees2.html (from rev 186984, trunk/LayoutTests/fast/regions/crash-when-renderer-is-in-multiple-selection-subtrees2.html) (0 => 189306)
--- branches/safari-601-branch/LayoutTests/fast/regions/crash-when-renderer-is-in-multiple-selection-subtrees2.html (rev 0)
+++ branches/safari-601-branch/LayoutTests/fast/regions/crash-when-renderer-is-in-multiple-selection-subtrees2.html 2015-09-03 23:03:59 UTC (rev 189306)
@@ -0,0 +1,23 @@
+<script>
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
+</script>
+<style>
+ div { -webkit-flow-into: content-flow; }
+ * { -webkit-flow-into: thread; }
+</style>
+<body _onload_="shuffle()"><p>PASS if no assert or crash.</p><div>content</div>foobar</body>
+<script>
+ document.execCommand("SelectAll");
+</script>
+<script>
+function shuffle() {
+ var element = document.getElementsByTagName("div")[0];
+ element.parentNode.removeChild(element);
+ document.body.offsetTop;
+ if (window.testRunner)
+ testRunner.notifyDone();
+}
+</script>
Modified: branches/safari-601-branch/Source/WebCore/ChangeLog (189305 => 189306)
--- branches/safari-601-branch/Source/WebCore/ChangeLog 2015-09-03 22:53:51 UTC (rev 189305)
+++ branches/safari-601-branch/Source/WebCore/ChangeLog 2015-09-03 23:03:59 UTC (rev 189306)
@@ -1,3 +1,29 @@
+2015-09-03 Babak Shafiei <[email protected]>
+
+ Merge r186984.
+
+ 2015-07-17 Zalan Bujtas <[email protected]>
+
+ REGRESSION (r169105): Do not assign a renderer to multiple selection subtrees.
+ https://bugs.webkit.org/show_bug.cgi?id=147038
+ rdar://problem/21819351
+
+ Reviewed by David Kilzer.
+
+ A renderer should never be assigned to multiple selection subtrees. (Currently RenderObject maintains the last selection state.)
+ RenderView::applySubtreeSelection() loops from the start to the end of the selection to find renderers that are inside the selection.
+ However, in case of regions (when multiple selection roots are present) traversing the renderer tree by calling RenderObject::nextInPreOrder() could
+ end up going across selection roots.
+ This patch ensures that we assign renderers to a specific selection only when the current selection root and the renderer's selection root match.
+
+ Test: fast/regions/crash-when-renderer-is-in-multiple-selection-subtrees2.html
+
+ * rendering/RenderView.cpp:
+ (WebCore::SelectionIterator::SelectionIterator):
+ (WebCore::SelectionIterator::current):
+ (WebCore::SelectionIterator::checkForSpanner):
+ (WebCore::RenderView::applySubtreeSelection):
+
2015-08-28 Babak Shafiei <[email protected]>
Merge r189024.
Modified: branches/safari-601-branch/Source/WebCore/rendering/RenderView.cpp (189305 => 189306)
--- branches/safari-601-branch/Source/WebCore/rendering/RenderView.cpp 2015-09-03 22:53:51 UTC (rev 189305)
+++ branches/safari-601-branch/Source/WebCore/rendering/RenderView.cpp 2015-09-03 23:03:59 UTC (rev 189306)
@@ -75,26 +75,14 @@
};
struct SelectionIterator {
- RenderObject* m_current;
- Vector<RenderMultiColumnSpannerPlaceholder*> m_spannerStack;
-
- SelectionIterator(RenderObject* o)
+ SelectionIterator(RenderObject* start)
+ : m_current(start)
{
- m_current = o;
checkForSpanner();
}
- void checkForSpanner()
+ RenderObject* current() const
{
- if (!is<RenderMultiColumnSpannerPlaceholder>(m_current))
- return;
- auto& placeholder = downcast<RenderMultiColumnSpannerPlaceholder>(*m_current);
- m_spannerStack.append(&placeholder);
- m_current = placeholder.spanner();
- }
-
- RenderObject* current()
- {
return m_current;
}
@@ -111,6 +99,19 @@
}
return m_current;
}
+
+private:
+ void checkForSpanner()
+ {
+ if (!is<RenderMultiColumnSpannerPlaceholder>(m_current))
+ return;
+ auto& placeholder = downcast<RenderMultiColumnSpannerPlaceholder>(*m_current);
+ m_spannerStack.append(&placeholder);
+ m_current = placeholder.spanner();
+ }
+
+ RenderObject* m_current { nullptr };
+ Vector<RenderMultiColumnSpannerPlaceholder*> m_spannerStack;
};
RenderView::RenderView(Document& document, Ref<RenderStyle>&& style)
@@ -1020,14 +1021,18 @@
root.selectionData().selectionEnd()->setSelectionStateIfNeeded(SelectionEnd);
}
- RenderObject* o = root.selectionData().selectionStart();
- RenderObject* stop = rendererAfterPosition(root.selectionData().selectionEnd(), root.selectionData().selectionEndPos());
- SelectionIterator selectionIterator(o);
-
- while (o && o != stop) {
- if (o != root.selectionData().selectionStart() && o != root.selectionData().selectionEnd() && o->canBeSelectionLeaf())
- o->setSelectionStateIfNeeded(SelectionInside);
- o = selectionIterator.next();
+ RenderObject* selectionStart = root.selectionData().selectionStart();
+ RenderObject* selectionEnd = rendererAfterPosition(root.selectionData().selectionEnd(), root.selectionData().selectionEndPos());
+ SelectionIterator selectionIterator(selectionStart);
+ for (RenderObject* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) {
+ if (currentRenderer == root.selectionData().selectionStart() || currentRenderer == root.selectionData().selectionEnd())
+ continue;
+ if (!currentRenderer->canBeSelectionLeaf())
+ continue;
+ // FIXME: Move this logic to SelectionIterator::next()
+ if (¤tRenderer->selectionRoot() != &root)
+ continue;
+ currentRenderer->setSelectionStateIfNeeded(SelectionInside);
}
if (blockRepaintMode != RepaintNothing)
@@ -1037,36 +1042,33 @@
// put them in the new objects list.
SelectedObjectMap newSelectedObjects;
SelectedBlockMap newSelectedBlocks;
- o = root.selectionData().selectionStart();
- selectionIterator = SelectionIterator(o);
- while (o && o != stop) {
- if (isValidObjectForNewSelection(root, *o)) {
- std::unique_ptr<RenderSelectionInfo> selectionInfo = std::make_unique<RenderSelectionInfo>(*o, true);
+ selectionIterator = SelectionIterator(selectionStart);
+ for (RenderObject* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) {
+ if (isValidObjectForNewSelection(root, *currentRenderer)) {
+ std::unique_ptr<RenderSelectionInfo> selectionInfo = std::make_unique<RenderSelectionInfo>(*currentRenderer, true);
#if ENABLE(SERVICE_CONTROLS)
for (auto& rect : selectionInfo->collectedSelectionRects())
m_selectionRectGatherer.addRect(selectionInfo->repaintContainer(), rect);
- if (!o->isTextOrLineBreak())
+ if (!currentRenderer->isTextOrLineBreak())
m_selectionRectGatherer.setTextOnly(false);
#endif
- newSelectedObjects.set(o, WTF::move(selectionInfo));
+ newSelectedObjects.set(currentRenderer, WTF::move(selectionInfo));
- RenderBlock* cb = o->containingBlock();
- while (cb && !cb->isRenderView()) {
- std::unique_ptr<RenderBlockSelectionInfo>& blockInfo = newSelectedBlocks.add(cb, nullptr).iterator->value;
+ RenderBlock* containingBlock = currentRenderer->containingBlock();
+ while (containingBlock && !containingBlock->isRenderView()) {
+ std::unique_ptr<RenderBlockSelectionInfo>& blockInfo = newSelectedBlocks.add(containingBlock, nullptr).iterator->value;
if (blockInfo)
break;
- blockInfo = std::make_unique<RenderBlockSelectionInfo>(*cb);
- cb = cb->containingBlock();
+ blockInfo = std::make_unique<RenderBlockSelectionInfo>(*containingBlock);
+ containingBlock = containingBlock->containingBlock();
#if ENABLE(SERVICE_CONTROLS)
m_selectionRectGatherer.addGapRects(blockInfo->repaintContainer(), blockInfo->rects());
#endif
}
}
-
- o = selectionIterator.next();
}
if (blockRepaintMode == RepaintNothing)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes