- Revision
- 196837
- Author
- [email protected]
- Date
- 2016-02-19 14:59:25 -0800 (Fri, 19 Feb 2016)
Log Message
Wheel event callback removing the window causes crash in WebCore.
https://bugs.webkit.org/show_bug.cgi?id=150871
Reviewed by Brent Fulgham.
Source/WebCore:
Null check the FrameView before using it, since the iframe may have been removed
from its parent document inside the event handler.
The new test triggered a cross-load side-effect, where wheel event filtering wasn't
reset between page loads. Fix by calling clearLatchedState() in EventHandler::clear(),
which resets the filtering.
Test: fast/events/wheel-event-destroys-frame.html
* page/EventHandler.cpp:
(WebCore::EventHandler::clear):
* page/WheelEventDeltaFilter.cpp:
(WebCore::WheelEventDeltaFilter::filteredDelta):
* page/mac/EventHandlerMac.mm:
(WebCore::EventHandler::platformCompleteWheelEvent):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::scrollTo):
LayoutTests:
* fast/events/wheel-event-destroys-frame-expected.txt: Added.
* fast/events/wheel-event-destroys-frame.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (196836 => 196837)
--- trunk/LayoutTests/ChangeLog 2016-02-19 22:56:31 UTC (rev 196836)
+++ trunk/LayoutTests/ChangeLog 2016-02-19 22:59:25 UTC (rev 196837)
@@ -1,3 +1,13 @@
+2016-02-19 Simon Fraser <[email protected]>
+
+ Wheel event callback removing the window causes crash in WebCore.
+ https://bugs.webkit.org/show_bug.cgi?id=150871
+
+ Reviewed by Brent Fulgham.
+
+ * fast/events/wheel-event-destroys-frame-expected.txt: Added.
+ * fast/events/wheel-event-destroys-frame.html: Added.
+
2016-02-19 Antti Koivisto <[email protected]>
ComposedTreeIterator traverses normal children for elements with empty shadow root
Added: trunk/LayoutTests/fast/events/wheel-event-destroys-frame-expected.txt (0 => 196837)
--- trunk/LayoutTests/fast/events/wheel-event-destroys-frame-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/wheel-event-destroys-frame-expected.txt 2016-02-19 22:59:25 UTC (rev 196837)
@@ -0,0 +1,3 @@
+This test should not crash
+
+
Added: trunk/LayoutTests/fast/events/wheel-event-destroys-frame.html (0 => 196837)
--- trunk/LayoutTests/fast/events/wheel-event-destroys-frame.html (rev 0)
+++ trunk/LayoutTests/fast/events/wheel-event-destroys-frame.html 2016-02-19 22:59:25 UTC (rev 196837)
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script>
+ if (window.testRunner) {
+ testRunner.waitUntilDone();
+ testRunner.dumpAsText();
+ }
+
+ function frameLoaded(iframe)
+ {
+ iframe.contentWindow.addEventListener('wheel', function() {
+ // Removing the window during event firing causes crash.
+ window.document.body.removeChild(iframe);
+ window.setTimeout(function() {
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }, 0);
+ });
+
+ if (!window.eventSender)
+ return;
+
+ var iframeTarget = document.getElementById('iframe');
+ var iframeBounds = iframeTarget.getBoundingClientRect();
+
+ eventSender.mouseMoveTo(iframeBounds.left + 10, iframeBounds.top + 10);
+ eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none');
+ eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none');
+ eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none');
+ eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none');
+ }
+ </script>
+</head>
+<body>
+ <p>This test should not crash</p>
+ <iframe id="iframe" _onload_="frameLoaded(this)" src="" here</body>"></iframe>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (196836 => 196837)
--- trunk/Source/WebCore/ChangeLog 2016-02-19 22:56:31 UTC (rev 196836)
+++ trunk/Source/WebCore/ChangeLog 2016-02-19 22:59:25 UTC (rev 196837)
@@ -1,3 +1,28 @@
+2016-02-19 Simon Fraser <[email protected]>
+
+ Wheel event callback removing the window causes crash in WebCore.
+ https://bugs.webkit.org/show_bug.cgi?id=150871
+
+ Reviewed by Brent Fulgham.
+
+ Null check the FrameView before using it, since the iframe may have been removed
+ from its parent document inside the event handler.
+
+ The new test triggered a cross-load side-effect, where wheel event filtering wasn't
+ reset between page loads. Fix by calling clearLatchedState() in EventHandler::clear(),
+ which resets the filtering.
+
+ Test: fast/events/wheel-event-destroys-frame.html
+
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::clear):
+ * page/WheelEventDeltaFilter.cpp:
+ (WebCore::WheelEventDeltaFilter::filteredDelta):
+ * page/mac/EventHandlerMac.mm:
+ (WebCore::EventHandler::platformCompleteWheelEvent):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::scrollTo):
+
2016-02-19 Myles C. Maxfield <[email protected]>
[Win] [SVG -> OTF Converter] All uses of a font except the first one are invisible
Modified: trunk/Source/WebCore/page/EventHandler.cpp (196836 => 196837)
--- trunk/Source/WebCore/page/EventHandler.cpp 2016-02-19 22:56:31 UTC (rev 196836)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2016-02-19 22:59:25 UTC (rev 196837)
@@ -452,9 +452,7 @@
m_mousePressed = false;
m_capturesDragging = false;
m_capturingMouseEventsElement = nullptr;
-#if PLATFORM(MAC)
- m_frame.mainFrame().resetLatchingState();
-#endif
+ clearLatchedState();
#if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
m_originatingTouchPointTargets.clear();
m_originatingTouchPointDocument = nullptr;
@@ -2664,7 +2662,8 @@
#if PLATFORM(MAC)
m_frame.mainFrame().resetLatchingState();
#endif
- m_frame.mainFrame().wheelEventDeltaFilter()->endFilteringDeltas();
+ if (WheelEventDeltaFilter* filter = m_frame.mainFrame().wheelEventDeltaFilter())
+ filter->endFilteringDeltas();
}
void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEvent)
Modified: trunk/Source/WebCore/page/WheelEventDeltaFilter.cpp (196836 => 196837)
--- trunk/Source/WebCore/page/WheelEventDeltaFilter.cpp 2016-02-19 22:56:31 UTC (rev 196836)
+++ trunk/Source/WebCore/page/WheelEventDeltaFilter.cpp 2016-02-19 22:59:25 UTC (rev 196837)
@@ -31,6 +31,8 @@
#endif
#include "FloatSize.h"
+#include "Logging.h"
+#include "TextStream.h"
namespace WebCore {
@@ -58,6 +60,7 @@
FloatSize WheelEventDeltaFilter::filteredDelta() const
{
+ LOG_WITH_STREAM(Scrolling, stream << "BasicWheelEventDeltaFilter::filteredDelta returning " << m_currentFilteredDelta);
return m_currentFilteredDelta;
}
Modified: trunk/Source/WebCore/page/mac/EventHandlerMac.mm (196836 => 196837)
--- trunk/Source/WebCore/page/mac/EventHandlerMac.mm 2016-02-19 22:56:31 UTC (rev 196836)
+++ trunk/Source/WebCore/page/mac/EventHandlerMac.mm 2016-02-19 22:59:25 UTC (rev 196837)
@@ -1008,9 +1008,10 @@
bool EventHandler::platformCompleteWheelEvent(const PlatformWheelEvent& wheelEvent, ContainerNode* scrollableContainer, ScrollableArea* scrollableArea)
{
+ FrameView* view = m_frame.view();
// We do another check on the frame view because the event handler can run JS which results in the frame getting destroyed.
- ASSERT(m_frame.view());
- FrameView* view = m_frame.view();
+ if (!view)
+ return false;
ScrollLatchingState* latchingState = m_frame.mainFrame().latchingState();
if (wheelEvent.useLatchedEventElement() && !latchingIsLockedToAncestorOfThisFrame(m_frame) && latchingState && latchingState->scrollableContainer()) {
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (196836 => 196837)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2016-02-19 22:56:31 UTC (rev 196836)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2016-02-19 22:59:25 UTC (rev 196837)
@@ -2349,6 +2349,8 @@
if (!box)
return;
+ LOG_WITH_STREAM(Scrolling, stream << "RenderLayer::scrollTo " << position);
+
ScrollPosition newPosition = position;
if (box->style().overflowX() != OMARQUEE) {
// Ensure that the dimensions will be computed if they need to be (for overflow:hidden blocks).