Title: [206889] trunk
Revision
206889
Author
cdu...@apple.com
Date
2016-10-06 17:16:36 -0700 (Thu, 06 Oct 2016)

Log Message

Overwriting an attribute event listener can lead to wrong event listener firing order
https://bugs.webkit.org/show_bug.cgi?id=163083

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Rebaseline a couple of W3C tests now that more checks are passing.

* web-platform-tests/html/webappapis/scripting/events/event-handler-spec-example-expected.txt:
* web-platform-tests/html/webappapis/scripting/events/inline-event-handler-ordering-expected.txt:

Source/WebCore:

Overwriting an attribute event listener could lead to wrong event listener
firing order in WebKit. This is because we were removing the old event
listener and then appending the new one instead of actually *replacing*
the old one.

No new tests, rebaselined existing tests.

* dom/EventListenerMap.cpp:
(WebCore::EventListenerMap::replace):
* dom/EventListenerMap.h:
* dom/EventTarget.cpp:
(WebCore::EventTarget::setAttributeEventListener):
(WebCore::EventTarget::hasActiveEventListeners): Deleted.
(WebCore::EventTarget::dispatchEventForBindings): Deleted.
* dom/EventTarget.h:

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (206888 => 206889)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2016-10-06 23:11:01 UTC (rev 206888)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2016-10-07 00:16:36 UTC (rev 206889)
@@ -1,3 +1,15 @@
+2016-10-06  Chris Dumez  <cdu...@apple.com>
+
+        Overwriting an attribute event listener can lead to wrong event listener firing order
+        https://bugs.webkit.org/show_bug.cgi?id=163083
+
+        Reviewed by Darin Adler.
+
+        Rebaseline a couple of W3C tests now that more checks are passing.
+
+        * web-platform-tests/html/webappapis/scripting/events/event-handler-spec-example-expected.txt:
+        * web-platform-tests/html/webappapis/scripting/events/inline-event-handler-ordering-expected.txt:
+
 2016-10-06  Jiewen Tan  <jiewen_...@apple.com>
 
         Add a dummy SubtleCrypto interface

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/events/event-handler-spec-example-expected.txt (206888 => 206889)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/events/event-handler-spec-example-expected.txt	2016-10-06 23:11:01 UTC (rev 206888)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/events/event-handler-spec-example-expected.txt	2016-10-07 00:16:36 UTC (rev 206889)
@@ -1,11 +1,11 @@
 
-FAIL Event handler listeners should be registered when they are first set to an object value (object "[object Object]"). assert_equals: expected 2 but got 1
-FAIL Event handler listeners should be registered when they are first set to an object value (function "function () {}"). assert_equals: expected 2 but got 1
-FAIL Event handler listeners should be registered when they are first set to an object value (object "42"). assert_equals: expected 2 but got 1
-FAIL Event handler listeners should be registered when they are first set to an object value (object ""). assert_equals: expected 2 but got 1
-FAIL Event handler listeners should be registered when they are first set to an object value (42). assert_equals: expected 3 but got 2
-FAIL Event handler listeners should be registered when they are first set to an object value (null). assert_equals: expected 3 but got 2
-FAIL Event handler listeners should be registered when they are first set to an object value (undefined). assert_equals: expected 3 but got 2
-FAIL Event handler listeners should be registered when they are first set to an object value (""). assert_equals: expected 3 but got 2
-FAIL Event handler listeners should be registered when they are first set to an object value. assert_equals: expected 3 but got 2
+PASS Event handler listeners should be registered when they are first set to an object value (object "[object Object]"). 
+PASS Event handler listeners should be registered when they are first set to an object value (function "function () {}"). 
+PASS Event handler listeners should be registered when they are first set to an object value (object "42"). 
+PASS Event handler listeners should be registered when they are first set to an object value (object ""). 
+PASS Event handler listeners should be registered when they are first set to an object value (42). 
+PASS Event handler listeners should be registered when they are first set to an object value (null). 
+PASS Event handler listeners should be registered when they are first set to an object value (undefined). 
+PASS Event handler listeners should be registered when they are first set to an object value (""). 
+PASS Event handler listeners should be registered when they are first set to an object value. 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/events/inline-event-handler-ordering-expected.txt (206888 => 206889)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/events/inline-event-handler-ordering-expected.txt	2016-10-06 23:11:01 UTC (rev 206888)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/events/inline-event-handler-ordering-expected.txt	2016-10-07 00:16:36 UTC (rev 206889)
@@ -3,7 +3,7 @@
 
 Harness Error (FAIL), message = SyntaxError: Unexpected token '}'
 
-FAIL Inline event handlers retain their ordering when invalid and force-compiled assert_array_equals: property 1, expected "TWO" but got "THREE"
-FAIL Inline event handlers retain their ordering when invalid and force-compiled via dispatch assert_array_equals: property 3, expected "TWO" but got "THREE"
-FAIL Inline event handlers retain their ordering when invalid and lazy-compiled assert_array_equals: property 1, expected "TWO" but got "THREE"
+PASS Inline event handlers retain their ordering when invalid and force-compiled 
+PASS Inline event handlers retain their ordering when invalid and force-compiled via dispatch 
+PASS Inline event handlers retain their ordering when invalid and lazy-compiled 
 

Modified: trunk/Source/WebCore/ChangeLog (206888 => 206889)


--- trunk/Source/WebCore/ChangeLog	2016-10-06 23:11:01 UTC (rev 206888)
+++ trunk/Source/WebCore/ChangeLog	2016-10-07 00:16:36 UTC (rev 206889)
@@ -1,3 +1,26 @@
+2016-10-06  Chris Dumez  <cdu...@apple.com>
+
+        Overwriting an attribute event listener can lead to wrong event listener firing order
+        https://bugs.webkit.org/show_bug.cgi?id=163083
+
+        Reviewed by Darin Adler.
+
+        Overwriting an attribute event listener could lead to wrong event listener
+        firing order in WebKit. This is because we were removing the old event
+        listener and then appending the new one instead of actually *replacing*
+        the old one.
+
+        No new tests, rebaselined existing tests.
+
+        * dom/EventListenerMap.cpp:
+        (WebCore::EventListenerMap::replace):
+        * dom/EventListenerMap.h:
+        * dom/EventTarget.cpp:
+        (WebCore::EventTarget::setAttributeEventListener):
+        (WebCore::EventTarget::hasActiveEventListeners): Deleted.
+        (WebCore::EventTarget::dispatchEventForBindings): Deleted.
+        * dom/EventTarget.h:
+
 2016-10-06  Alex Christensen  <achristen...@webkit.org>
 
         URLParser: Non-ASCII characters in Non-UTF-8 encoded queries of relative URLs with ws, wss, or nonspecial schemes should be UTF-8 encoded

Modified: trunk/Source/WebCore/dom/EventListenerMap.cpp (206888 => 206889)


--- trunk/Source/WebCore/dom/EventListenerMap.cpp	2016-10-06 23:11:01 UTC (rev 206888)
+++ trunk/Source/WebCore/dom/EventListenerMap.cpp	2016-10-07 00:16:36 UTC (rev 206889)
@@ -108,6 +108,19 @@
     return notFound;
 }
 
+void EventListenerMap::replace(const AtomicString& eventType, EventListener& oldListener, Ref<EventListener>&& newListener, const RegisteredEventListener::Options& options)
+{
+    assertNoActiveIterators();
+
+    auto* listeners = find(eventType);
+    ASSERT(listeners);
+    size_t index = findListener(*listeners, oldListener, options.capture);
+    ASSERT(index != notFound);
+    auto& registeredListener = listeners->at(index);
+    registeredListener->markAsRemoved();
+    registeredListener = RegisteredEventListener::create(WTFMove(newListener), options);
+}
+
 bool EventListenerMap::add(const AtomicString& eventType, Ref<EventListener>&& listener, const RegisteredEventListener::Options& options)
 {
     assertNoActiveIterators();

Modified: trunk/Source/WebCore/dom/EventListenerMap.h (206888 => 206889)


--- trunk/Source/WebCore/dom/EventListenerMap.h	2016-10-06 23:11:01 UTC (rev 206888)
+++ trunk/Source/WebCore/dom/EventListenerMap.h	2016-10-07 00:16:36 UTC (rev 206889)
@@ -55,6 +55,7 @@
 
     void clear();
 
+    void replace(const AtomicString& eventType, EventListener& oldListener, Ref<EventListener>&& newListener, const RegisteredEventListener::Options&);
     bool add(const AtomicString& eventType, Ref<EventListener>&&, const RegisteredEventListener::Options&);
     bool remove(const AtomicString& eventType, EventListener&, bool useCapture);
     WEBCORE_EXPORT EventListenerVector* find(const AtomicString& eventType) const;

Modified: trunk/Source/WebCore/dom/EventTarget.cpp (206888 => 206889)


--- trunk/Source/WebCore/dom/EventTarget.cpp	2016-10-06 23:11:01 UTC (rev 206888)
+++ trunk/Source/WebCore/dom/EventTarget.cpp	2016-10-07 00:16:36 UTC (rev 206889)
@@ -107,11 +107,17 @@
 
 bool EventTarget::setAttributeEventListener(const AtomicString& eventType, RefPtr<EventListener>&& listener)
 {
-    clearAttributeEventListener(eventType);
-    if (!listener)
+    EventListener* existingListener = getAttributeEventListener(eventType);
+    if (!listener) {
+        if (existingListener)
+            removeEventListener(eventType, *existingListener, false);
         return false;
-    return addEventListener(eventType, listener.releaseNonNull());
-}
+    }
+    if (existingListener) {
+        eventTargetData()->eventListenerMap.replace(eventType, *existingListener, listener.releaseNonNull(), { });
+        return true;
+    }
+    return addEventListener(eventType, listener.releaseNonNull());}
 
 EventListener* EventTarget::getAttributeEventListener(const AtomicString& eventType)
 {
@@ -130,14 +136,6 @@
     return eventTargetData->eventListenerMap.containsActive(eventType);
 }
 
-bool EventTarget::clearAttributeEventListener(const AtomicString& eventType)
-{
-    EventListener* listener = getAttributeEventListener(eventType);
-    if (!listener)
-        return false;
-    return removeEventListener(eventType, *listener, false);
-}
-
 bool EventTarget::dispatchEventForBindings(Event& event, ExceptionCode& ec)
 {
     event.setUntrusted();

Modified: trunk/Source/WebCore/dom/EventTarget.h (206888 => 206889)


--- trunk/Source/WebCore/dom/EventTarget.h	2016-10-06 23:11:01 UTC (rev 206888)
+++ trunk/Source/WebCore/dom/EventTarget.h	2016-10-07 00:16:36 UTC (rev 206889)
@@ -151,7 +151,6 @@
 
     // Used for legacy "onEvent" attribute APIs.
     bool setAttributeEventListener(const AtomicString& eventType, RefPtr<EventListener>&&);
-    bool clearAttributeEventListener(const AtomicString& eventType);
     EventListener* getAttributeEventListener(const AtomicString& eventType);
 
     bool hasEventListeners() const;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to