Bug 505988. Don't unwrap when we shouldn't. r=bz

--HG--
extra : rebase_source : d251c442ba2fae0f9ffcae99c2c84d780c99ea52
This commit is contained in:
Blake Kaplan 2009-07-30 15:26:59 +12:00
Родитель e9f662e5fb
Коммит 7ebe7c87bd
4 изменённых файлов: 70 добавлений и 41 удалений

Просмотреть файл

@ -4007,7 +4007,7 @@ public:
jsval GetJSVal() const {return mJSVal;} jsval GetJSVal() const {return mJSVal;}
XPCVariant(jsval aJSVal); XPCVariant(XPCCallContext& ccx, jsval aJSVal);
/** /**
* Convert a variant into a jsval. * Convert a variant into a jsval.
@ -4032,6 +4032,7 @@ protected:
protected: protected:
nsDiscriminatedUnion mData; nsDiscriminatedUnion mData;
jsval mJSVal; jsval mJSVal;
JSBool mReturnRawObject;
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(XPCVariant, XPCVARIANT_IID) NS_DEFINE_STATIC_IID_ACCESSOR(XPCVariant, XPCVARIANT_IID)
@ -4040,10 +4041,10 @@ class XPCTraceableVariant: public XPCVariant,
public XPCRootSetElem public XPCRootSetElem
{ {
public: public:
XPCTraceableVariant(XPCJSRuntime *runtime, jsval aJSVal) XPCTraceableVariant(XPCCallContext& ccx, jsval aJSVal)
: XPCVariant(aJSVal) : XPCVariant(ccx, aJSVal)
{ {
runtime->AddVariantRoot(this); ccx.GetRuntime()->AddVariantRoot(this);
} }
virtual ~XPCTraceableVariant(); virtual ~XPCTraceableVariant();

Просмотреть файл

@ -55,10 +55,26 @@ NS_IMPL_CI_INTERFACE_GETTER2(XPCVariant, XPCVariant, nsIVariant)
NS_IMPL_CYCLE_COLLECTING_ADDREF(XPCVariant) NS_IMPL_CYCLE_COLLECTING_ADDREF(XPCVariant)
NS_IMPL_CYCLE_COLLECTING_RELEASE(XPCVariant) NS_IMPL_CYCLE_COLLECTING_RELEASE(XPCVariant)
XPCVariant::XPCVariant(jsval aJSVal) XPCVariant::XPCVariant(XPCCallContext& ccx, jsval aJSVal)
: mJSVal(aJSVal) : mJSVal(aJSVal)
{ {
nsVariant::Initialize(&mData); nsVariant::Initialize(&mData);
if(!JSVAL_IS_PRIMITIVE(mJSVal))
{
// If the incoming object is an XPCWrappedNative, then it could be a
// double-wrapped object, and we should return the double-wrapped
// object back out to script.
JSObject* proto;
XPCWrappedNative* wn =
XPCWrappedNative::GetWrappedNativeOfJSObject(ccx,
JSVAL_TO_OBJECT(mJSVal),
nsnull,
&proto);
mReturnRawObject = !wn && !proto;
}
else
mReturnRawObject = JS_FALSE;
} }
XPCTraceableVariant::~XPCTraceableVariant() XPCTraceableVariant::~XPCTraceableVariant()
@ -119,9 +135,9 @@ XPCVariant* XPCVariant::newVariant(XPCCallContext& ccx, jsval aJSVal)
XPCVariant* variant; XPCVariant* variant;
if(!JSVAL_IS_TRACEABLE(aJSVal)) if(!JSVAL_IS_TRACEABLE(aJSVal))
variant = new XPCVariant(aJSVal); variant = new XPCVariant(ccx, aJSVal);
else else
variant = new XPCTraceableVariant(ccx.GetRuntime(), aJSVal); variant = new XPCTraceableVariant(ccx, aJSVal);
if(!variant) if(!variant)
return nsnull; return nsnull;
@ -401,6 +417,15 @@ XPCVariant::VariantDataToJS(XPCCallContext& ccx,
return JS_TRUE; return JS_TRUE;
} }
if(xpcvariant->mReturnRawObject)
{
NS_ASSERTION(type == nsIDataType::VTYPE_INTERFACE ||
type == nsIDataType::VTYPE_INTERFACE_IS,
"Weird variant");
*pJSVal = realVal;
return JS_TRUE;
}
// else, it's an object and we really need to double wrap it if we've // else, it's an object and we really need to double wrap it if we've
// already decided that its 'natural' type is as some sort of interface. // already decided that its 'natural' type is as some sort of interface.
@ -641,40 +666,10 @@ VARIANT_DONE:
} }
else else
{ {
// Last ditch check to prevent us from double-wrapping a regular JS success = XPCConvert::NativeData2JS(ccx, pJSVal,
// object. This allows us to unwrap regular JS objects (since we (const void*)&xpctvar.val,
// normally can't double wrap them). See bug 384632. xpctvar.type,
*pJSVal = JSVAL_VOID; &iid, scope, pErr);
if(type == nsIDataType::VTYPE_INTERFACE ||
type == nsIDataType::VTYPE_INTERFACE_IS)
{
nsISupports *src = reinterpret_cast<nsISupports *>(xpctvar.val.p);
if(nsXPCWrappedJSClass::IsWrappedJS(src))
{
// First QI the wrapper to the right interface.
nsCOMPtr<nsISupports> wrapper;
nsresult rv = src->QueryInterface(iid, getter_AddRefs(wrapper));
NS_ENSURE_SUCCESS(rv, JS_FALSE);
// Now, get the actual JS object out of the wrapper.
nsCOMPtr<nsIXPConnectJSObjectHolder> holder =
do_QueryInterface(wrapper);
NS_ENSURE_TRUE(holder, JS_FALSE);
JSObject *obj;
holder->GetJSObject(&obj);
NS_ASSERTION(obj, "No JS object but the QIs above succeeded?");
*pJSVal = OBJECT_TO_JSVAL(obj);
success = JS_TRUE;
}
}
if(!JSVAL_IS_OBJECT(*pJSVal))
{
success = XPCConvert::NativeData2JS(ccx, pJSVal,
(const void*)&xpctvar.val,
xpctvar.type,
&iid, scope, pErr);
}
} }
if(xpctvar.IsValAllocated()) if(xpctvar.IsValAllocated())

Просмотреть файл

@ -47,6 +47,7 @@ include $(topsrcdir)/config/rules.mk
_TEST_FILES = bug500931_helper.html \ _TEST_FILES = bug500931_helper.html \
inner.html \ inner.html \
test_bug361111.xul \ test_bug361111.xul \
test_bug384632.html \
test_bug390488.html \ test_bug390488.html \
test_bug393269.html \ test_bug393269.html \
test_bug396851.html \ test_bug396851.html \

Просмотреть файл

@ -0,0 +1,32 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=384632
-->
<head>
<title>Test for Bug 384632</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=384632">Mozilla Bug 384632</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 384632 **/
var div = $('content');
var obj = {};
div.setUserData("foopy", obj, function() {});
ok(div.getUserData("foopy") === obj, "getUserData works with regular objects");
div.setUserData("foopy1", sidebar, function() {});
ok(div.getUserData("foopy1") === sidebar, "getUserData works with bizarre objects");
</script>
</pre>
</body>
</html>