Bug 883096 - Crash at nsEventListenerManager::GetListenerInfo, r=jst
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Fri, 14 Jun 2013 20:10:22 +0300
changeset 146587 d22a6e206de0c2b54309f6c6fff226920afabd6c
parent 146586 f5c81bdff6108d4cf142da7f1b479880e385fbf6
child 146588 5527906f11f5edd0e6bf3320816c31e01655729e
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst
bugs883096
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 883096 - Crash at nsEventListenerManager::GetListenerInfo, r=jst
content/events/public/nsIEventListenerService.idl
content/events/src/nsEventListenerManager.cpp
content/events/test/test_bug448602.html
--- a/content/events/public/nsIEventListenerService.idl
+++ b/content/events/public/nsIEventListenerService.idl
@@ -11,16 +11,17 @@ interface nsIDOMEventTarget;
  * An instance of this interface describes how an event listener
  * was added to an event target.
  */
 [scriptable, uuid(c4776eb7-05bc-49ce-a0ca-6213a346d53a)]
 interface nsIEventListenerInfo : nsISupports
 {
   /**
    * The type of the event for which the listener was added.
+   * Null if the listener is for all the events.
    */
   readonly attribute AString type;
   readonly attribute boolean capturing;
   readonly attribute boolean allowsUntrusted;
   readonly attribute boolean inSystemEventGroup;
 
   /**
    * The underlying JS object of the event listener, if this listener
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -1162,18 +1162,22 @@ nsEventListenerManager::GetListenerInfo(
   for (uint32_t i = 0; i < count; ++i) {
     const nsListenerStruct& ls = mListeners.ElementAt(i);
     // If this is a script handler and we haven't yet
     // compiled the event handler itself go ahead and compile it
     if ((ls.mListenerType == eJSEventListener) && ls.mHandlerIsString) {
       CompileEventHandlerInternal(const_cast<nsListenerStruct*>(&ls),
                                   true, nullptr);
     }
-    const nsDependentSubstring& eventType =
-      Substring(nsDependentAtomString(ls.mTypeAtom), 2);
+    nsAutoString eventType;
+    if (ls.mAllEvents) {
+      eventType.SetIsVoid(true);
+    } else {
+      eventType.Assign(Substring(nsDependentAtomString(ls.mTypeAtom), 2));
+    }
     // EventListenerInfo is defined in XPCOM, so we have to go ahead
     // and convert to an XPCOM callback here...
     nsRefPtr<nsEventListenerInfo> info =
       new nsEventListenerInfo(eventType, ls.mListener.ToXPCOMCallback(),
                               ls.mFlags.mCapture,
                               ls.mFlags.mAllowUntrustedEvents,
                               ls.mFlags.mInSystemGroup);
     NS_ENSURE_TRUE(info, NS_ERROR_OUT_OF_MEMORY);
--- a/content/events/test/test_bug448602.html
+++ b/content/events/test/test_bug448602.html
@@ -179,16 +179,25 @@ function testAllListener() {
                    target: e.target.id,
                    phase: e.eventPhase,
                    trusted: e.isTrusted
                   });
     e.stopPropagation();
   }
 
   els.addListenerForAllEvents(root, allListener, false, true);
+  var infos = els.getListenerInfoFor(root);
+  var nullTypes = 0;
+  for (var i = 0; i < infos.length; ++i) {
+    if (infos[i].type == null) {
+      ++nullTypes;
+    }
+  }
+  is(nullTypes, 1, "Should have one all-event-listener!");
+
   els.addListenerForAllEvents(root, allListener, false, true, true);
   els.addListenerForAllEvents(root, allListenerTrustedOnly, false, false, true);
   l3.dispatchEvent(new Event("testevent", { bubbles: true }));
   dispatchTrusted(l3, { bubbles: true });
   els.removeListenerForAllEvents(root, allListener, false);
   els.removeListenerForAllEvents(root, allListener, false, true);
   els.removeListenerForAllEvents(root, allListenerTrustedOnly, false, true);
   // make sure removeListenerForAllEvents works.