[iOS] Crash in WebCore::DOMWindow::incrementScrollEventListenersCount
https://bugs.webkit.org/show_bug.cgi?id=202878

Reviewed by Alex Christensen.

Source/WebCore:

Added the missing null check in tryAddEventListener and tryRemoveEventListener for scroll event.

Test: fast/events/scroll-event-on-document-without-window.html

* dom/Node.cpp:
(WebCore::tryAddEventListener):
(WebCore::tryRemoveEventListener):

LayoutTests:

Added a regression test for the crash.

* fast/events/scroll-event-on-document-without-window-expected.txt: Added.
* fast/events/scroll-event-on-document-without-window.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@251057 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 22f0f93..c2b5796 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,5 +1,17 @@
 2019-10-12  Ryosuke Niwa  <rniwa@webkit.org>
 
+        [iOS] Crash in WebCore::DOMWindow::incrementScrollEventListenersCount
+        https://bugs.webkit.org/show_bug.cgi?id=202878
+
+        Reviewed by Alex Christensen.
+
+        Added a regression test for the crash.
+
+        * fast/events/scroll-event-on-document-without-window-expected.txt: Added.
+        * fast/events/scroll-event-on-document-without-window.html: Added.
+
+2019-10-12  Ryosuke Niwa  <rniwa@webkit.org>
+
         Invoke callback registered by requestIdleCallback
         https://bugs.webkit.org/show_bug.cgi?id=202824
 
diff --git a/LayoutTests/fast/events/scroll-event-on-document-without-window-expected.txt b/LayoutTests/fast/events/scroll-event-on-document-without-window-expected.txt
new file mode 100644
index 0000000..810e3ff
--- /dev/null
+++ b/LayoutTests/fast/events/scroll-event-on-document-without-window-expected.txt
@@ -0,0 +1,3 @@
+This tests add scroll event listener to a document without browsing context. WebKit should not crash.
+
+PASS
diff --git a/LayoutTests/fast/events/scroll-event-on-document-without-window.html b/LayoutTests/fast/events/scroll-event-on-document-without-window.html
new file mode 100644
index 0000000..8d048cb
--- /dev/null
+++ b/LayoutTests/fast/events/scroll-event-on-document-without-window.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This tests add scroll event listener to a document without browsing context. WebKit should not crash.</p>
+<script>
+
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+const doc = document.implementation.createHTMLDocument();
+function listner() { }
+doc.addEventListener('scroll', listner);
+doc.removeEventListener('scroll', listner);
+
+document.write('PASS');
+
+</script>
+</body>
+</html>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 0e985aa..9eb815f 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,18 @@
+2019-10-12  Ryosuke Niwa  <rniwa@webkit.org>
+
+        [iOS] Crash in WebCore::DOMWindow::incrementScrollEventListenersCount
+        https://bugs.webkit.org/show_bug.cgi?id=202878
+
+        Reviewed by Alex Christensen.
+
+        Added the missing null check in tryAddEventListener and tryRemoveEventListener for scroll event.
+
+        Test: fast/events/scroll-event-on-document-without-window.html
+
+        * dom/Node.cpp:
+        (WebCore::tryAddEventListener):
+        (WebCore::tryRemoveEventListener):
+
 2019-10-12  Simon Fraser  <simon.fraser@apple.com>
 
         Move CSSReflectionDirection into RenderStyleConstants as ReflectionDirection
diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp
index 9801b17..cded7de 100644
--- a/Source/WebCore/dom/Node.cpp
+++ b/Source/WebCore/dom/Node.cpp
@@ -2114,8 +2114,10 @@
         targetNode->document().didAddTouchEventHandler(*targetNode);
 
 #if PLATFORM(IOS_FAMILY)
-    if (targetNode == &targetNode->document() && eventType == eventNames().scrollEvent)
-        targetNode->document().domWindow()->incrementScrollEventListenersCount();
+    if (targetNode == &targetNode->document() && eventType == eventNames().scrollEvent) {
+        if (auto* window = targetNode->document().domWindow())
+            targetNode->document().domWindow()->incrementScrollEventListenersCount();
+    }
 
 #if ENABLE(TOUCH_EVENTS)
     if (eventNames().isTouchRelatedEventType(targetNode->document(), eventType))
@@ -2149,8 +2151,10 @@
         targetNode->document().didRemoveTouchEventHandler(*targetNode);
 
 #if PLATFORM(IOS_FAMILY)
-    if (targetNode == &targetNode->document() && eventType == eventNames().scrollEvent)
-        targetNode->document().domWindow()->decrementScrollEventListenersCount();
+    if (targetNode == &targetNode->document() && eventType == eventNames().scrollEvent) {
+        if (auto* window = targetNode->document().domWindow())
+            window->decrementScrollEventListenersCount();
+    }
 
 #if ENABLE(TOUCH_EVENTS)
     if (eventNames().isTouchRelatedEventType(targetNode->document(), eventType))