Bug 689128, re-enable EventListenerService tests, add a null check, handle compartments, r=bz
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Mon, 10 Oct 2011 13:38:14 +0300
changeset 79111 4c02f4104c17503e7455c3a216a16db501627d40
parent 79110 bcf12565b95b9df0ebd91c7d511225c2a28c88ce
child 79112 50f9a6fb25dbc1437d730ddf42966ecfd77b0c21
push id506
push userclegnitto@mozilla.com
push dateWed, 09 Nov 2011 02:03:18 +0000
treeherdermozilla-aurora@63587fc7bb93 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs689128
milestone10.0a1
Bug 689128, re-enable EventListenerService tests, add a null check, handle compartments, r=bz
content/base/src/nsInProcessTabChildGlobal.cpp
content/base/src/nsInProcessTabChildGlobal.h
content/events/src/nsEventListenerService.cpp
content/events/src/nsEventListenerService.h
content/events/test/Makefile.in
content/events/test/test_bug448602.html
dom/base/nsDOMClassInfo.cpp
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
--- a/content/base/src/nsInProcessTabChildGlobal.cpp
+++ b/content/base/src/nsInProcessTabChildGlobal.cpp
@@ -143,36 +143,36 @@ nsInProcessTabChildGlobal::Init()
                                               nsnull,
                                               mCx);
   return NS_OK;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsInProcessTabChildGlobal)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsInProcessTabChildGlobal,
-                                                nsDOMEventTargetHelper)
+                                                nsDOMEventTargetWrapperCache)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mMessageManager)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mGlobal)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsInProcessTabChildGlobal,
-                                                  nsDOMEventTargetHelper)
+                                                  nsDOMEventTargetWrapperCache)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mMessageManager)
   nsFrameScriptExecutor::Traverse(tmp, cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsInProcessTabChildGlobal)
   NS_INTERFACE_MAP_ENTRY(nsIFrameMessageManager)
   NS_INTERFACE_MAP_ENTRY(nsISyncMessageSender)
   NS_INTERFACE_MAP_ENTRY(nsIContentFrameMessageManager)
   NS_INTERFACE_MAP_ENTRY(nsIInProcessContentFrameMessageManager)
   NS_INTERFACE_MAP_ENTRY(nsIScriptContextPrincipal)
   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ContentFrameMessageManager)
-NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetWrapperCache)
 
 NS_IMPL_ADDREF_INHERITED(nsInProcessTabChildGlobal, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(nsInProcessTabChildGlobal, nsDOMEventTargetHelper)
 
 NS_IMETHODIMP
 nsInProcessTabChildGlobal::GetContent(nsIDOMWindow** aContent)
 {
   *aContent = nsnull;
--- a/content/base/src/nsInProcessTabChildGlobal.h
+++ b/content/base/src/nsInProcessTabChildGlobal.h
@@ -37,39 +37,39 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsInProcessTabChildGlobal_h
 #define nsInProcessTabChildGlobal_h
 
 #include "nsCOMPtr.h"
 #include "nsFrameMessageManager.h"
 #include "nsIScriptContext.h"
-#include "nsDOMEventTargetHelper.h"
+#include "nsDOMEventTargetWrapperCache.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIScriptContext.h"
 #include "nsIClassInfo.h"
 #include "jsapi.h"
 #include "nsIDocShell.h"
 #include "nsIDOMElement.h"
 #include "nsCOMArray.h"
 #include "nsThreadUtils.h"
 
-class nsInProcessTabChildGlobal : public nsDOMEventTargetHelper,
+class nsInProcessTabChildGlobal : public nsDOMEventTargetWrapperCache,
                                   public nsFrameScriptExecutor,
                                   public nsIInProcessContentFrameMessageManager,
                                   public nsIScriptObjectPrincipal,
                                   public nsIScriptContextPrincipal
 {
 public:
   nsInProcessTabChildGlobal(nsIDocShell* aShell, nsIContent* aOwner,
                             nsFrameMessageManager* aChrome);
   virtual ~nsInProcessTabChildGlobal();
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsInProcessTabChildGlobal,
-                                           nsDOMEventTargetHelper)
+                                           nsDOMEventTargetWrapperCache)
   NS_FORWARD_SAFE_NSIFRAMEMESSAGEMANAGER(mMessageManager)
   NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
                              const jsval& aObject,
                              JSContext* aCx,
                              PRUint8 aArgc,
                              jsval* aRetval)
   {
     return mMessageManager
--- a/content/events/src/nsEventListenerService.cpp
+++ b/content/events/src/nsEventListenerService.cpp
@@ -94,54 +94,60 @@ nsEventListenerInfo::GetInSystemEventGro
   *aInSystemEventGroup = mInSystemEventGroup;
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS1(nsEventListenerService, nsIEventListenerService)
 
 // Caller must root *aJSVal!
 bool
-nsEventListenerInfo::GetJSVal(jsval* aJSVal)
+nsEventListenerInfo::GetJSVal(JSContext* aCx, JSAutoEnterCompartment& aAc, jsval* aJSVal)
 {
   *aJSVal = JSVAL_NULL;
   nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS = do_QueryInterface(mListener);
   if (wrappedJS) {
     JSObject* object = nsnull;
-    wrappedJS->GetJSObject(&object);
+    if (NS_FAILED(wrappedJS->GetJSObject(&object)) || !aAc.enter(aCx, object)) {
+      return false;
+    }
     *aJSVal = OBJECT_TO_JSVAL(object);
-    return PR_TRUE;
+    return true;
   }
 
   nsCOMPtr<nsIJSEventListener> jsl = do_QueryInterface(mListener);
   if (jsl) {
-    void *handler = jsl->GetHandler();
+    JSObject *handler = static_cast<JSObject*>(jsl->GetHandler());
     if (handler) {
-      *aJSVal = OBJECT_TO_JSVAL(static_cast<JSObject*>(handler));
-      return PR_TRUE;
+      if (!aAc.enter(aCx, handler)) {
+        return false;
+      }
+      *aJSVal = OBJECT_TO_JSVAL(handler);
+      return true;
     }
   }
-  return PR_FALSE;
+  return false;
 }
 
 NS_IMETHODIMP
 nsEventListenerInfo::ToSource(nsAString& aResult)
 {
   aResult.SetIsVoid(PR_TRUE);
 
   nsCOMPtr<nsIThreadJSContextStack> stack =
     nsContentUtils::ThreadJSContextStack();
   if (stack) {
     JSContext* cx = nsnull;
     stack->GetSafeJSContext(&cx);
     if (cx && NS_SUCCEEDED(stack->Push(cx))) {
       {
         // Extra block to finish the auto request before calling pop
         JSAutoRequest ar(cx);
+        JSAutoEnterCompartment ac;
         jsval v = JSVAL_NULL;
-        if (GetJSVal(&v)) {
+        if (GetJSVal(cx, ac, &v)) {
           JSString* str = JS_ValueToSource(cx, v);
           if (str) {
             nsDependentJSString depStr;
             if (depStr.init(cx, str)) {
               aResult.Assign(depStr);
             }
           }
         }
@@ -172,19 +178,19 @@ nsEventListenerInfo::GetDebugObject(nsIS
     nsContentUtils::ThreadJSContextStack();
   if (stack) {
     JSContext* cx = nsnull;
     stack->GetSafeJSContext(&cx);
     if (cx && NS_SUCCEEDED(stack->Push(cx))) {
       {
         // Extra block to finish the auto request before calling pop
         JSAutoRequest ar(cx);
-
+        JSAutoEnterCompartment ac;
         jsval v = JSVAL_NULL;
-        if (GetJSVal(&v)) {
+        if (GetJSVal(cx, ac, &v)) {
           nsCOMPtr<jsdIValue> jsdValue;
           jsd->WrapJSValue(v, getter_AddRefs(jsdValue));
           *aRetVal = jsdValue.forget().get();
         }
       }
       stack->Pop(&cx);
     }
   }
@@ -193,16 +199,17 @@ nsEventListenerInfo::GetDebugObject(nsIS
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsEventListenerService::GetListenerInfoFor(nsIDOMEventTarget* aEventTarget,
                                            PRUint32* aCount,
                                            nsIEventListenerInfo*** aOutArray)
 {
+  NS_ENSURE_ARG_POINTER(aEventTarget);
   *aCount = 0;
   *aOutArray = nsnull;
   nsCOMArray<nsIEventListenerInfo> listenerInfos;
   nsEventListenerManager* elm =
     aEventTarget->GetListenerManager(PR_FALSE);
   if (elm) {
     elm->GetListenerInfo(&listenerInfos);
   }
--- a/content/events/src/nsEventListenerService.h
+++ b/content/events/src/nsEventListenerService.h
@@ -55,17 +55,17 @@ public:
   : mType(aType), mListener(aListener), mCapturing(aCapturing),
     mAllowsUntrusted(aAllowsUntrusted),
     mInSystemEventGroup(aInSystemEventGroup) {}
   virtual ~nsEventListenerInfo() {}
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(nsEventListenerInfo)
   NS_DECL_NSIEVENTLISTENERINFO
 protected:
-  bool GetJSVal(jsval* aJSVal);
+  bool GetJSVal(JSContext* aCx, JSAutoEnterCompartment& aAc, jsval* aJSVal);
 
   nsString                      mType;
   // nsReftPtr because that is what nsListenerStruct uses too.
   nsRefPtr<nsIDOMEventListener> mListener;
   bool                          mCapturing;
   bool                          mAllowsUntrusted;
   bool                          mInSystemEventGroup;
 };
--- a/content/events/test/Makefile.in
+++ b/content/events/test/Makefile.in
@@ -41,18 +41,16 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = content/events/test
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 # Disabled due to timeouts.
 # 		test_bug563329.html
-# Disabled due to lack of present support for JSD in JM
-#		test_bug448602.html
 _TEST_FILES = \
 		test_bug226361.xhtml \
 		     bug226361_iframe.xhtml \
 		test_bug238987.html \
 		test_bug288392.html \
 		test_bug299673-1.html \
 		test_bug299673-2.html \
 		     bug299673.js \
@@ -69,16 +67,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug405632.html \
 		test_bug409604.html \
 		test_bug412567.html \
 		test_bug426082.html \
 		test_bug427537.html \
 		test_bug432698.html \
 		test_bug443985.html \
 		test_bug447736.html \
+		test_bug448602.html \
 		test_bug450876.html \
 		test_bug456273.html \
 		test_bug457672.html \
 		test_bug428988.html \
 		bug457672.html \
 		test_draggableprop.html \
 		test_bug489671.html \
 		test_bug502818.html \
--- a/content/events/test/test_bug448602.html
+++ b/content/events/test/test_bug448602.html
@@ -17,19 +17,22 @@ https://bugzilla.mozilla.org/show_bug.cg
 <pre id="test">          
 <script type="application/javascript">
 
 /** Test for Bug 448602 **/
 
 
 function runTests() {
   netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+/*
+  Disabled due to lack of present support for JSD in JM
   var jsdIDebuggerService = Components.interfaces.jsdIDebuggerService;
   var jsd = Components.classes['@mozilla.org/js/jsd/debugger-service;1']
                       .getService(jsdIDebuggerService);
+*/
   var els = Components.classes["@mozilla.org/eventlistenerservice;1"]
                       .getService(Components.interfaces.nsIEventListenerService);
 
   // Event listener info tests
   var root = document.getElementById("testroot");
   var infos = els.getListenerInfoFor(root, {});
   is(infos.length, 0, "Element shouldn't have listeners (1)");
 
@@ -38,53 +41,59 @@ function runTests() {
   infos = els.getListenerInfoFor(root, {});
   is(infos.length, 1, "Element should have listeners (1)");
   is(infos[0].toSource(), 'function onclick(event) {' + listenerSource + '}',
      "Unexpected serialization (1)");
   is(infos[0].type, "click", "Wrong type (1)");
   is(infos[0].capturing, false, "Wrong phase (1)");
   is(infos[0].allowsUntrusted, true, "Should allow untrusted events (1)");
 
+/*
   var jsdOn = jsd.isOn;
   if (!jsdOn) {
     is(infos[0].getDebugObject(), null,
        "If JSD isn't running, getDebugObject() should return null.")
     jsd.on();
     ok(jsd.isOn, "JSD should be running.");
   }
   var jsdvalue = infos[0].getDebugObject().QueryInterface(Components.interfaces.jsdIValue);
   is(jsdvalue.jsType, 3, "Event listener should be a function! (1)");
+*/
 
   root.removeAttribute("onclick");
   infos = els.getListenerInfoFor(root, {});
   is(infos.length, 0, "Element shouldn't have listeners (2)");
 
   var l = function (e) { alert(e); };
   root.addEventListener("foo", l, true, true);
   root.addEventListener("foo", l, false, false);
   infos = els.getListenerInfoFor(root, {});
   is(infos.length, 2, "Element should have listeners (2)");
   is(infos[0].toSource(), "(function (e) {alert(e);})",
      "Unexpected serialization (2)");
   is(infos[0].type, "foo", "Wrong type (2)");
   is(infos[0].capturing, true, "Wrong phase (2)");
   is(infos[0].allowsUntrusted, true, "Should allow untrusted events (2)");
+/*
   jsdvalue = infos[0].getDebugObject().QueryInterface(Components.interfaces.jsdIValue);
   is(jsdvalue.jsType, 3, "Event listener should be a function!(2)");
   is(jsdvalue.getWrappedValue(), l, "Wrong JS value! (1)");
+*/
 
   is(infos[1].toSource(), "(function (e) {alert(e);})",
      "Unexpected serialization (3)");
   is(infos[1].type, "foo", "Wrong type (3)");
   is(infos[1].capturing, false, "Wrong phase (3)");
   is(infos[1].allowsUntrusted, false, "Shouldn't allow untrusted events (1)");
 
+/*
   jsdvalue2 = infos[1].getDebugObject().QueryInterface(Components.interfaces.jsdIValue);
   is(jsdvalue2.jsType, 3, "Event listener should be a function! (3)");
   is(jsdvalue2.getWrappedValue(), l, "Wrong JS value! (2)");
+*/
   root.removeEventListener("foo", l, true);
   root.removeEventListener("foo", l, false);
   infos = els.getListenerInfoFor(root, {});
   is(infos.length, 0, "Element shouldn't have listeners (3)");
 
   root.onclick = l;
   infos = els.getListenerInfoFor(root, {});
   is(infos.length, 1, "Element should have listeners (3)");
@@ -112,22 +121,29 @@ function runTests() {
       hasDocumentInChain = true;
     } else if (chain[i] == window) {
       hasWindowInChain = true;
     }
   }
 
   ok(hasDocumentInChain, "Should have document in event target chain!");
   ok(hasWindowInChain, "Should have window in event target chain!");
-
+/*
   if (!jsdOn) {
     jsd.off();
     ok(!jsd.isOn, "JSD shouldn't be running anymore.");
   }
+*/	
 
+  try {
+    els.getListenerInfoFor(null, {});
+    ok(false, "Should have thrown an exception.");
+  } catch (ex) {
+    ok(true, "We should be still running.");
+  }
   
   SimpleTest.finish();
 }
 
 
 SimpleTest.waitForExplicitFinish();
 addLoadEvent(runTests);
 </script>
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1458,17 +1458,17 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(HashChangeEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(EventListenerInfo, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(TransitionEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(AnimationEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(ContentFrameMessageManager, nsDOMGenericSH,
+  NS_DEFINE_CLASSINFO_DATA(ContentFrameMessageManager, nsEventTargetSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(FormData, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(DesktopNotification, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(DesktopNotificationCenter, nsDOMGenericSH,
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -1037,33 +1037,33 @@ TabChildGlobal::~TabChildGlobal()
   if (mListenerManager) {
     mListenerManager->Disconnect();
   }
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(TabChildGlobal)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TabChildGlobal,
-                                                nsDOMEventTargetHelper)
+                                                nsDOMEventTargetWrapperCache)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mMessageManager)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TabChildGlobal,
-                                                  nsDOMEventTargetHelper)
+                                                  nsDOMEventTargetWrapperCache)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mMessageManager)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChildGlobal)
   NS_INTERFACE_MAP_ENTRY(nsIFrameMessageManager)
   NS_INTERFACE_MAP_ENTRY(nsISyncMessageSender)
   NS_INTERFACE_MAP_ENTRY(nsIContentFrameMessageManager)
   NS_INTERFACE_MAP_ENTRY(nsIScriptContextPrincipal)
   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ContentFrameMessageManager)
-NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetWrapperCache)
 
 NS_IMPL_ADDREF_INHERITED(TabChildGlobal, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(TabChildGlobal, nsDOMEventTargetHelper)
 
 NS_IMETHODIMP
 TabChildGlobal::GetContent(nsIDOMWindow** aContent)
 {
   *aContent = nsnull;
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -60,17 +60,17 @@
 #include "nsIDOMWindow.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDocument.h"
 #include "nsNetUtil.h"
 #include "nsFrameMessageManager.h"
 #include "nsIScriptContext.h"
-#include "nsDOMEventTargetHelper.h"
+#include "nsDOMEventTargetWrapperCache.h"
 #include "nsIDialogCreator.h"
 #include "nsIDialogParamBlock.h"
 #include "nsIPresShell.h"
 #include "nsIPrincipal.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIScriptContext.h"
 #include "nsWeakReference.h"
 #include "nsITabChild.h"
@@ -82,26 +82,26 @@ namespace layout {
 class RenderFrameChild;
 }
 
 namespace dom {
 
 class TabChild;
 class PContentDialogChild;
 
-class TabChildGlobal : public nsDOMEventTargetHelper,
+class TabChildGlobal : public nsDOMEventTargetWrapperCache,
                        public nsIContentFrameMessageManager,
                        public nsIScriptObjectPrincipal,
                        public nsIScriptContextPrincipal
 {
 public:
   TabChildGlobal(TabChild* aTabChild);
   ~TabChildGlobal();
   NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TabChildGlobal, nsDOMEventTargetHelper)
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TabChildGlobal, nsDOMEventTargetWrapperCache)
   NS_FORWARD_SAFE_NSIFRAMEMESSAGEMANAGER(mMessageManager)
   NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
                              const jsval& aObject,
                              JSContext* aCx,
                              PRUint8 aArgc,
                              jsval* aRetval)
   {
     return mMessageManager