[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.16-1409-g5afdf4d
dglazkov at chromium.org
dglazkov at chromium.org
Thu Dec 3 13:27:57 UTC 2009
The following commit has been merged in the webkit-1.1 branch:
commit 23e6909a7e83e704dc7e0f7e4155fcab98d6e890
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