Bug 763343 - Handle classinfo singletons in cross-compartment wrapping. r=peterv
authorBobby Holley <bobbyholley@gmail.com>
Fri, 13 Jul 2012 14:33:25 +0200
changeset 104469 43e70deac1241da9c04f0b28877136a3fb196cfc
parent 104468 ab3a6f89cb7f9e14a205cdd292477ab90a0428e8
child 104470 784d3448dfe3b68f420d225d1cd2a78dd1418342
push id191
push userlsblakk@mozilla.com
push dateFri, 05 Oct 2012 17:12:53 +0000
treeherdermozilla-release@ddb22ac6c03b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs763343
milestone16.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 763343 - Handle classinfo singletons in cross-compartment wrapping. r=peterv
dom/base/nsDOMClassInfo.cpp
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/tests/chrome/Makefile.in
js/xpconnect/tests/chrome/test_bug763343.xul
xpcom/components/nsIClassInfo.idl
xpcom/glue/nsIClassInfoImpl.h
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -604,17 +604,19 @@ static const char kDOMStringBundleURL[] 
 #define EVENTTARGET_SCRIPTABLE_FLAGS                                          \
   (DOM_DEFAULT_SCRIPTABLE_FLAGS       |                                       \
    nsIXPCScriptable::WANT_ADDPROPERTY)
 
 #define IDBEVENTTARGET_SCRIPTABLE_FLAGS                                       \
   (EVENTTARGET_SCRIPTABLE_FLAGS)
 
 #define DOMCLASSINFO_STANDARD_FLAGS                                           \
-  (nsIClassInfo::MAIN_THREAD_ONLY | nsIClassInfo::DOM_OBJECT)
+  (nsIClassInfo::MAIN_THREAD_ONLY |                                           \
+   nsIClassInfo::DOM_OBJECT       |                                           \
+   nsIClassInfo::SINGLETON_CLASSINFO)
 
 
 #ifdef DEBUG
 #define NS_DEFINE_CLASSINFO_DATA_DEBUG(_class)                                \
     eDOMClassInfo_##_class##_id,
 #else
 #define NS_DEFINE_CLASSINFO_DATA_DEBUG(_class)                                \
   // nothing
@@ -10707,17 +10709,17 @@ nsDOMConstructorSH::HasInstance(nsIXPCon
 }
 
 NS_IMETHODIMP
 nsNonDOMObjectSH::GetFlags(PRUint32 *aFlags)
 {
   // This is NOT a DOM Object.  Use this helper class for cases when you need
   // to do something like implement nsISecurityCheckedComponent in a meaningful
   // way.
-  *aFlags = nsIClassInfo::MAIN_THREAD_ONLY;
+  *aFlags = nsIClassInfo::MAIN_THREAD_ONLY | nsIClassInfo::SINGLETON_CLASSINFO;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAttributeSH::GetFlags(PRUint32 *aFlags)
 {
   // Just like nsNodeSH, but without CONTENT_NODE
   *aFlags = DOMCLASSINFO_STANDARD_FLAGS;
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -482,18 +482,24 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
     //
     // To handle this we need to get the scriptable helper early and ask it.
     // It is possible that we will then end up forwarding this entire call
     // to this same function but with a different scope.
 
     // If we are making a wrapper for the nsIClassInfo interface then
     // We *don't* want to have it use the prototype meant for instances
     // of that class.
-    JSBool isClassInfo = Interface &&
-                         Interface->GetIID()->Equals(NS_GET_IID(nsIClassInfo));
+    bool iidIsClassInfo = Interface &&
+                          Interface->GetIID()->Equals(NS_GET_IID(nsIClassInfo));
+    PRUint32 classInfoFlags;
+    bool isClassInfoSingleton = helper.GetClassInfo() == helper.Object() &&
+                                NS_SUCCEEDED(helper.GetClassInfo()
+                                                   ->GetFlags(&classInfoFlags)) &&
+                                (classInfoFlags & nsIClassInfo::SINGLETON_CLASSINFO);
+    bool isClassInfo = iidIsClassInfo || isClassInfoSingleton;
 
     nsIClassInfo *info = helper.GetClassInfo();
 
     XPCNativeScriptableCreateInfo sciProto;
     XPCNativeScriptableCreateInfo sci;
 
     // Gather scriptable create info if we are wrapping something
     // other than an nsIClassInfo object. We need to not do this for
--- a/js/xpconnect/tests/chrome/Makefile.in
+++ b/js/xpconnect/tests/chrome/Makefile.in
@@ -7,55 +7,56 @@ topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 relativesrcdir  = js/xpconnect/tests/chrome
 
 include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_CHROME_FILES = \
 		test_bug448587.xul \
+		test_bug484459.xul \
 		test_bug500931.xul \
 		bug503926.xul \
 		test_bug503926.xul \
+		test_bug517163.xul \
 		test_bug533596.xul \
-		test_doublewrappedcompartments.xul \
-		test_evalInSandbox.xul \
-		file_evalInSandbox.html \
-		test_sandboxImport.xul \
-		test_wrappers.xul \
-		test_bug484459.xul \
-		test_cows.xul \
-		test_bug517163.xul \
 		test_bug571849.xul \
+		test_bug596580.xul \
 		test_bug601803.xul \
 		test_bug610390.xul \
 		test_bug614757.xul \
 		test_bug616992.xul \
 		test_bug618176.xul \
 		file_bug618176.xul \
-		test_bug596580.xul \
 		test_bug654370.xul \
 		test_bug658560.xul \
+		test_bug664689.xul \
 		test_bug679861.xul \
-		test_bug664689.xul \
 		test_bug706301.xul \
+		test_bug726949.xul \
 		test_bug743843.xul \
+		test_bug758563.xul \
+		test_bug760076.xul \
+		test_bug763343.xul \
 		test_APIExposer.xul \
-		test_precisegc.xul \
-		test_nodelists.xul \
-		test_getweakmapkeys.xul \
-		test_weakmaps.xul \
+		test_cows.xul \
+		test_documentdomain.xul \
+		test_doublewrappedcompartments.xul \
+		test_evalInSandbox.xul \
+		file_evalInSandbox.html \
 		test_exnstack.xul \
-		test_weakref.xul \
-		test_bug726949.xul \
 		test_expandosharing.xul \
 		file_expandosharing.jsm \
-		test_bug758563.xul \
-		test_bug760076.xul \
-		test_documentdomain.xul \
+		test_getweakmapkeys.xul \
+		test_nodelists.xul \
+		test_precisegc.xul \
+		test_sandboxImport.xul \
+		test_weakmaps.xul \
+		test_weakref.xul \
+		test_wrappers.xul \
 		$(NULL)
 
 # Disabled until this test gets updated to test the new proxy based
 # wrappers.
 #		test_wrappers-2.xul \
 
 # Disabled due to apparent conservative stack scanner false positives on Linux64 debug.
 #		test_watchpoints.xul \
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/chrome/test_bug763343.xul
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=763343
+-->
+<window title="Mozilla Bug 763343"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+  <!-- test results are displayed in the html:body -->
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=763343"
+     target="_blank">Mozilla Bug 763343</a>
+  </body>
+
+  <!-- test code goes here -->
+  <script type="application/javascript">
+  <![CDATA[
+
+  /** Test for Cross-compartment nsIClassInfo singleton wrapping. **/
+  const Cc = Components.classes;
+  const Ci = Components.interfaces;
+  const Cu = Components.utils;
+
+  var singleton = window.QueryInterface(Ci.nsIClassInfo);
+  var sb = new Cu.Sandbox(window);
+
+  // Don't crash.
+  sb.singleton = singleton;
+  ok(true, "didn't crash");
+
+  ]]>
+  </script>
+</window>
--- a/xpcom/components/nsIClassInfo.idl
+++ b/xpcom/components/nsIClassInfo.idl
@@ -78,16 +78,17 @@ interface nsIClassInfo : nsISupports
     /**
      * Bitflags for 'flags' attribute.
      */
     const PRUint32 SINGLETON            = 1 << 0;
     const PRUint32 THREADSAFE           = 1 << 1;
     const PRUint32 MAIN_THREAD_ONLY     = 1 << 2;
     const PRUint32 DOM_OBJECT           = 1 << 3;
     const PRUint32 PLUGIN_OBJECT        = 1 << 4;
+    const PRUint32 SINGLETON_CLASSINFO  = 1 << 5;
 
     /**
      * 'flags' attribute bitflag: whether objects of this type implement
      * nsIContent.
      */
     const PRUint32 CONTENT_NODE         = 1 << 6;
     
     // The high order bit is RESERVED for consumers of these flags. 
--- a/xpcom/glue/nsIClassInfoImpl.h
+++ b/xpcom/glue/nsIClassInfoImpl.h
@@ -111,17 +111,17 @@ private:
   extern NS_IMETHODIMP NS_CI_INTERFACE_GETTER_NAME(_class)                    \
      (PRUint32 * NS_OUTPARAM, nsIID *** NS_OUTPARAM);
 
 #define NS_IMPL_CLASSINFO(_class, _getlanguagehelper, _flags, _cid)     \
   NS_DECL_CI_INTERFACE_GETTER(_class)                                   \
   static const GenericClassInfo::ClassInfoData k##_class##ClassInfoData = { \
     NS_CI_INTERFACE_GETTER_NAME(_class),                                \
     _getlanguagehelper,                                                 \
-    _flags,                                                             \
+    _flags | nsIClassInfo::SINGLETON_CLASSINFO,                         \
     _cid,                                                               \
   };                                                                    \
   static char k##_class##ClassInfoDataPlace[sizeof(GenericClassInfo)];  \
   nsIClassInfo* NS_CLASSINFO_NAME(_class) = NULL;
 
 #define NS_IMPL_QUERY_CLASSINFO(_class)                                       \
   if ( aIID.Equals(NS_GET_IID(nsIClassInfo)) ) {                              \
     if (!NS_CLASSINFO_NAME(_class))                                           \