Bug 622301 - Don't use XPCWrappedNative::GetWrappedNativeOfJSObject in quickstub unwrapping. r=mrbkap

This commit is contained in:
Bobby Holley 2012-01-14 10:29:56 -08:00
parent e36848b82c
commit 5cde0ddc16

View File

@ -783,17 +783,54 @@ getWrapper(JSContext *cx,
JSObject **cur,
XPCWrappedNativeTearOff **tearoff)
{
if (XPCWrapper::IsSecurityWrapper(obj) &&
!(obj = XPCWrapper::Unwrap(cx, obj))) {
return NS_ERROR_XPC_SECURITY_MANAGER_VETO;
// We can have at most three layers in need of unwrapping here:
// * A (possible) security wrapper
// * A (possible) Xray waiver
// * A (possible) outer window
//
// The underlying call to js::Unwrap recursively unwraps, but stops if it
// hits an outer object. Thus, we need to make at most two unwrapping
// calls: one to handle security wrappers and waivers, and one to handle
// outer objects.
if (js::IsWrapper(obj)) {
obj = XPCWrapper::Unwrap(cx, obj);
if (obj && js::IsWrapper(obj)) {
MOZ_ASSERT(js::Wrapper::wrapperHandler(obj)->isOuterWindow());
obj = XPCWrapper::Unwrap(cx, obj);
}
// The safe unwrap might have failed for SCRIPT_ACCESS_ONLY objects. If it
// didn't fail though, we should be done with wrappers.
if (!obj)
return NS_ERROR_XPC_SECURITY_MANAGER_VETO;
MOZ_ASSERT(!js::IsWrapper(obj));
}
*cur = obj;
// Start with sane values.
*wrapper = nsnull;
*cur = nsnull;
*tearoff = nsnull;
*wrapper =
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj, callee, cur,
tearoff);
// Handle tearoffs.
//
// If |obj| is of the tearoff class, that means we're dealing with a JS
// object reflection of a particular interface (ie, |foo.nsIBar|). These
// JS objects are parented to their wrapper, so we snag the tearoff object
// along the way (if desired), and then set |obj| to its parent.
if (js::GetObjectClass(obj) == &XPC_WN_Tearoff_JSClass) {
*tearoff = (XPCWrappedNativeTearOff*) js::GetObjectPrivate(obj);
obj = js::GetObjectParent(obj);
}
// If we've got a WN or slim wrapper, store things the way callers expect.
// Otherwise, leave things null and return.
if (IS_WRAPPER_CLASS(js::GetObjectClass(obj))) {
if (IS_WN_WRAPPER_OBJECT(obj))
*wrapper = (XPCWrappedNative*) js::GetObjectPrivate(obj);
else
*cur = obj;
}
return NS_OK;
}