Bug 763343 - Handle classinfo singletons in cross-compartment wrapping. r=peterv
--- 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)) \