[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

dglazkov at chromium.org dglazkov at chromium.org
Wed Apr 7 23:24:07 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit fca5c5cf754f7912555614250fb0e35a35fc0cca
Author: dglazkov at chromium.org <dglazkov at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Nov 5 20:09:12 2009 +0000

    WebCore:
    
    2009-11-05  Vitaly Repeshko  <vitalyr at chromium.org>
    
            Reviewed by Geoffrey Garen and Dimitri Glazkov.
    
            Rehashing of EventListenerMap leads to loss of EvenListenerList.
            https://bugs.webkit.org/show_bug.cgi?id=31027
    
            Tested by new fast/events/event-listener-map-rehash-crash.html.
    
            EventListenerMap modified to store pointers to listener vectors:
            * dom/EventTarget.cpp:
            (WebCore::EventTargetData::~EventTargetData):
            (WebCore::EventTarget::addEventListener):
            (WebCore::EventTarget::removeEventListener):
            (WebCore::EventTarget::fireEventListeners):
            (WebCore::EventTarget::getEventListeners):
            (WebCore::EventTarget::removeAllEventListeners):
            * dom/EventTarget.h:
    
            Usages updated after interface changes:
            * inspector/InspectorDOMAgent.cpp:
            (WebCore::InspectorDOMAgent::getEventListenersForNode):
            * svg/SVGUseElement.cpp:
            (WebCore::SVGUseElement::transferEventListenersToShadowTree):
    
    LayoutTests:
    
    2009-11-05  Dimitri Glazkov  <dglazkov at chromium.org>
    
            Reviewed by Geoffrey Garen.
    
            Rehashing of EventListenerMap leads to loss of EvenListenerList.
            https://bugs.webkit.org/show_bug.cgi?id=31027
    
            * fast/events/event-listener-map-rehash-crash.html: Added.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@50573 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 446754e..4a7e44e 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,12 @@
+2009-11-05  Dimitri Glazkov  <dglazkov at chromium.org>
+
+        Reviewed by Geoffrey Garen.
+
+        Rehashing of EventListenerMap leads to loss of EvenListenerList.
+        https://bugs.webkit.org/show_bug.cgi?id=31027
+
+        * fast/events/event-listener-map-rehash-crash.html: Added.
+
 2009-11-05  Brian Weinstein  <bweinstein at apple.com>
 
         Rubber-stamped by Adam Roben.
diff --git a/LayoutTests/fast/events/event-listener-map-rehash-crash-expected.txt b/LayoutTests/fast/events/event-listener-map-rehash-crash-expected.txt
new file mode 100644
index 0000000..9b53ba3
--- /dev/null
+++ b/LayoutTests/fast/events/event-listener-map-rehash-crash-expected.txt
@@ -0,0 +1,9 @@
+Ensures that rehashing of events map doesn't leave us with a dangling event list reference.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Did not crash.
+PASS successfullyParsed is true
+
+TEST COMPLETE
diff --git a/LayoutTests/fast/events/event-listener-map-rehash-crash.html b/LayoutTests/fast/events/event-listener-map-rehash-crash.html
new file mode 100644
index 0000000..4e81e14
--- /dev/null
+++ b/LayoutTests/fast/events/event-listener-map-rehash-crash.html
@@ -0,0 +1,28 @@
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+<script>
+    function stub() {}
+
+    document.addEventListener("DOMContentLoaded", function()
+    {
+        for (var i = 0; i < 50; ++i)
+            document.addEventListener("boom" + i, stub, false);
+    }, false);
+
+    document.addEventListener("DOMContentLoaded", stub);
+
+    var successfullyParsed = true;
+</script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+    description("Ensures that rehashing of events map doesn't leave us with a dangling event list reference.");
+    testPassed("Did not crash.");
+</script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 89a634f..f7d3ebd 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,28 @@
+2009-11-05  Vitaly Repeshko  <vitalyr at chromium.org>
+
+        Reviewed by Geoffrey Garen and Dimitri Glazkov.
+
+        Rehashing of EventListenerMap leads to loss of EvenListenerList.
+        https://bugs.webkit.org/show_bug.cgi?id=31027
+
+        Tested by new fast/events/event-listener-map-rehash-crash.html.
+
+        EventListenerMap modified to store pointers to listener vectors:
+        * dom/EventTarget.cpp:
+        (WebCore::EventTargetData::~EventTargetData):
+        (WebCore::EventTarget::addEventListener):
+        (WebCore::EventTarget::removeEventListener):
+        (WebCore::EventTarget::fireEventListeners):
+        (WebCore::EventTarget::getEventListeners):
+        (WebCore::EventTarget::removeAllEventListeners):
+        * dom/EventTarget.h:
+
+        Usages updated after interface changes:
+        * inspector/InspectorDOMAgent.cpp:
+        (WebCore::InspectorDOMAgent::getEventListenersForNode):
+        * svg/SVGUseElement.cpp:
+        (WebCore::SVGUseElement::transferEventListenersToShadowTree):
+
 2009-11-05  Dan Kegel  <dank at chromium.org>
 
         Reviewed by Dmitri Titov.
diff --git a/WebCore/dom/EventTarget.cpp b/WebCore/dom/EventTarget.cpp
index 694e78a..b064854 100644
--- a/WebCore/dom/EventTarget.cpp
+++ b/WebCore/dom/EventTarget.cpp
@@ -68,6 +68,11 @@ bool eventDispatchForbidden()
 }
 #endif // NDEBUG
 
+EventTargetData::~EventTargetData()
+{
+    deleteAllValues(eventListenerMap);
+}
+
 EventTarget::~EventTarget()
 {
 }
@@ -157,16 +162,19 @@ bool EventTarget::addEventListener(const AtomicString& eventType, PassRefPtr<Eve
 {
     EventTargetData* d = ensureEventTargetData();
 
-    pair<EventListenerMap::iterator, bool> result = d->eventListenerMap.add(eventType, EventListenerVector());
-    EventListenerVector& entry = result.first->second;
+    pair<EventListenerMap::iterator, bool> result = d->eventListenerMap.add(eventType, 0);
+    EventListenerVector*& entry = result.first->second;
+    const bool isNewEntry = result.second;
+    if (isNewEntry)
+        entry = new EventListenerVector();
 
     RegisteredEventListener registeredListener(listener, useCapture);
-    if (!result.second) { // pre-existing entry
-        if (entry.find(registeredListener) != notFound) // duplicate listener
+    if (!isNewEntry) {
+        if (entry->find(registeredListener) != notFound) // duplicate listener
             return false;
     }
 
-    entry.append(registeredListener);
+    entry->append(registeredListener);
     return true;
 }
 
@@ -179,16 +187,18 @@ bool EventTarget::removeEventListener(const AtomicString& eventType, EventListen
     EventListenerMap::iterator result = d->eventListenerMap.find(eventType);
     if (result == d->eventListenerMap.end())
         return false;
-    EventListenerVector& entry = result->second;
+    EventListenerVector* entry = result->second;
 
     RegisteredEventListener registeredListener(listener, useCapture);
-    size_t index = entry.find(registeredListener);
+    size_t index = entry->find(registeredListener);
     if (index == notFound)
         return false;
 
-    entry.remove(index);
-    if (!entry.size())
+    entry->remove(index);
+    if (entry->isEmpty()) {
+        delete entry;
         d->eventListenerMap.remove(result);
+    }
 
     // Notify firing events planning to invoke the listener at 'index' that
     // they have one less listener to invoke.
@@ -266,7 +276,7 @@ bool EventTarget::fireEventListeners(Event* event)
     EventListenerMap::iterator result = d->eventListenerMap.find(event->type());
     if (result == d->eventListenerMap.end())
         return false;
-    EventListenerVector& entry = result->second;
+    EventListenerVector& entry = *result->second;
 
     RefPtr<EventTarget> protect = this;
 
@@ -303,7 +313,7 @@ const EventListenerVector& EventTarget::getEventListeners(const AtomicString& ev
     EventListenerMap::iterator it = d->eventListenerMap.find(eventType);
     if (it == d->eventListenerMap.end())
         return emptyVector;
-    return it->second;
+    return *it->second;
 }
 
 void EventTarget::removeAllEventListeners()
@@ -311,6 +321,7 @@ void EventTarget::removeAllEventListeners()
     EventTargetData* d = eventTargetData();
     if (!d)
         return;
+    deleteAllValues(d->eventListenerMap);
     d->eventListenerMap.clear();
 
     // Notify firing events planning to invoke the listener at 'index' that
diff --git a/WebCore/dom/EventTarget.h b/WebCore/dom/EventTarget.h
index 1e51f04..2d77c87 100644
--- a/WebCore/dom/EventTarget.h
+++ b/WebCore/dom/EventTarget.h
@@ -76,9 +76,11 @@ namespace WebCore {
     typedef Vector<FiringEventIterator, 1> FiringEventIteratorVector;
 
     typedef Vector<RegisteredEventListener, 1> EventListenerVector;
-    typedef HashMap<AtomicString, EventListenerVector> EventListenerMap;
+    typedef HashMap<AtomicString, EventListenerVector*> EventListenerMap;
 
     struct EventTargetData : Noncopyable {
+        ~EventTargetData();
+
         EventListenerMap eventListenerMap;
         FiringEventIteratorVector firingEventIterators;
     };
@@ -190,7 +192,7 @@ namespace WebCore {
 
         EventListenerMap::iterator end = d->eventListenerMap.end();
         for (EventListenerMap::iterator it = d->eventListenerMap.begin(); it != end; ++it) {
-            EventListenerVector& entry = it->second;
+            EventListenerVector& entry = *it->second;
             for (size_t i = 0; i < entry.size(); ++i)
                 entry[i].listener->markJSFunction(markStack);
         }
@@ -202,6 +204,7 @@ namespace WebCore {
         if (!d)
             return;
 
+        deleteAllValues(d->eventListenerMap);
         d->eventListenerMap.clear();
     }
 #endif
diff --git a/WebCore/inspector/InspectorDOMAgent.cpp b/WebCore/inspector/InspectorDOMAgent.cpp
index f6c2d46..c7f7f53 100644
--- a/WebCore/inspector/InspectorDOMAgent.cpp
+++ b/WebCore/inspector/InspectorDOMAgent.cpp
@@ -380,8 +380,8 @@ void InspectorDOMAgent::getEventListenersForNode(long callId, long nodeId)
     // Get the list of event types this Node is concerned with
     Vector<AtomicString> eventTypes;
     const EventListenerMap& listenerMap = d->eventListenerMap;
-    HashMap<AtomicString, EventListenerVector>::const_iterator end = listenerMap.end();
-    for (HashMap<AtomicString, EventListenerVector>::const_iterator iter = listenerMap.begin(); iter != end; ++iter)
+    EventListenerMap::const_iterator end = listenerMap.end();
+    for (EventListenerMap::const_iterator iter = listenerMap.begin(); iter != end; ++iter)
         eventTypes.append(iter->first);
 
     // Quick break if no useful listeners
diff --git a/WebCore/svg/SVGUseElement.cpp b/WebCore/svg/SVGUseElement.cpp
index 42517bd..1675977 100644
--- a/WebCore/svg/SVGUseElement.cpp
+++ b/WebCore/svg/SVGUseElement.cpp
@@ -772,7 +772,7 @@ void SVGUseElement::transferEventListenersToShadowTree(SVGElementInstance* targe
             EventListenerMap& map = d->eventListenerMap;
             EventListenerMap::iterator end = map.end();
             for (EventListenerMap::iterator it = map.begin(); it != end; ++it) {
-                EventListenerVector& entry = it->second;
+                EventListenerVector& entry = *it->second;
                 for (size_t i = 0; i < entry.size(); ++i) {
                     // Event listeners created from markup have already been transfered to the shadow tree during cloning.
                     if (entry[i].listener->wasCreatedFromMarkup())

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list