Bug 1371259 part 4. Stop using UnwrapArg to unwrap this values. r=peterv

This commit is contained in:
Boris Zbarsky 2017-07-10 16:05:25 -04:00
parent 5c76874a46
commit cdd8fe10d4
3 changed files with 70 additions and 11 deletions

View File

@ -3298,6 +3298,40 @@ UnwrapArgImpl(JSContext* cx,
return wrappedJS->QueryInterface(iid, ppArg);
}
nsresult
UnwrapXPConnectImpl(JSContext* cx,
JS::MutableHandle<JS::Value> src,
const nsIID &iid,
void **ppArg)
{
if (!NS_IsMainThread()) {
return NS_ERROR_NOT_AVAILABLE;
}
MOZ_ASSERT(src.isObject());
// Unwrap ourselves, because we're going to want access to the unwrapped
// object.
JS::Rooted<JSObject*> obj(cx,
js::CheckedUnwrap(&src.toObject(),
/* stopAtWindowProxy = */ false));
if (!obj) {
return NS_ERROR_NOT_AVAILABLE;
}
nsISupports *iface = xpc::UnwrapReflectorToISupports(obj);
if (!iface) {
return NS_ERROR_XPC_BAD_CONVERT_JS;
}
if (NS_FAILED(iface->QueryInterface(iid, ppArg))) {
return NS_ERROR_XPC_BAD_CONVERT_JS;
}
// Now update our source to keep rooting our object.
src.setObject(*obj);
return NS_OK;
}
nsresult
UnwrapWindowProxyImpl(JSContext* cx,
JS::Handle<JSObject*> src,

View File

@ -60,7 +60,8 @@ nsresult
UnwrapWindowProxyImpl(JSContext* cx, JS::Handle<JSObject*> src,
nsPIDOMWindowOuter** ppArg);
/** Convert a jsval to an XPCOM pointer. */
/** Convert a jsval to an XPCOM pointer. Caller must not assume that src will
keep the XPCOM pointer rooted. */
template <class Interface>
inline nsresult
UnwrapArg(JSContext* cx, JS::Handle<JSObject*> src, Interface** ppArg)
@ -77,6 +78,29 @@ UnwrapArg<nsPIDOMWindowOuter>(JSContext* cx, JS::Handle<JSObject*> src,
return UnwrapWindowProxyImpl(cx, src, ppArg);
}
nsresult
UnwrapXPConnectImpl(JSContext* cx, JS::MutableHandle<JS::Value> src,
const nsIID& iid, void** ppArg);
/*
* Convert a jsval being used as a Web IDL interface implementation to an XPCOM
* pointer; this is only used for Web IDL interfaces that specify
* hasXPConnectImpls. This is not the same as UnwrapArg because caller _can_
* assume that if unwrapping succeeds "val" will be updated so it's rooting the
* XPCOM pointer. Also, UnwrapXPConnect doesn't need to worry about doing
* XPCWrappedJS things.
*
* val must be an ObjectValue.
*/
template<class Interface>
inline nsresult
UnwrapXPConnect(JSContext* cx, JS::MutableHandle<JS::Value> val,
Interface** ppThis)
{
return UnwrapXPConnectImpl(cx, val, NS_GET_TEMPLATE_IID(Interface),
reinterpret_cast<void**>(ppThis));
}
bool
ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs,
bool aSecurityError, const char* aInterfaceName);

View File

@ -4337,6 +4337,14 @@ class CastableObjectUnwrapper():
"target": target,
"codeOnFailure": codeOnFailure,
}
# Supporting both the "cross origin object" case and the "has
# XPConnect impls" case at the same time is a pain, so let's
# not do that. That allows us to assume that our source is
# always a Handle or MutableHandle.
if allowCrossOriginObj and descriptor.hasXPConnectImpls:
raise TypeError("Interface %s both allows a cross-origin 'this' "
"and has XPConnect impls. We don't support that" %
descriptor.name)
if allowCrossOriginObj:
self.substitution["uncheckedObjDecl"] = fill(
"""
@ -4357,22 +4365,15 @@ class CastableObjectUnwrapper():
codeOnFailure=(codeOnFailure % { 'securityError': 'true'}))
self.substitution["source"] = "maybeUncheckedObj"
self.substitution["mutableSource"] = "&maybeUncheckedObj"
xpconnectUnwrap = dedent("""
nsresult rv;
{ // Scope for the JSAutoCompartment, because we only
// want to be in that compartment for the UnwrapArg call.
JSAutoCompartment ac(cx, ${source});
rv = UnwrapArg<${type}>(cx, ${source}, getter_AddRefs(objPtr));
}
""")
# No need to set up xpconnectUnwrap, since it won't be
# used in the allowCrossOriginObj case.
else:
self.substitution["uncheckedObjDecl"] = ""
self.substitution["uncheckedObjGet"] = ""
self.substitution["source"] = source
self.substitution["mutableSource"] = mutableSource
xpconnectUnwrap = (
"JS::Rooted<JSObject*> source(cx, &${source}.toObject());\n"
"nsresult rv = UnwrapArg<${type}>(cx, source, getter_AddRefs(objPtr));\n")
"nsresult rv = UnwrapXPConnect<${type}>(cx, ${mutableSource}, getter_AddRefs(objPtr));\n")
if descriptor.hasXPConnectImpls:
self.substitution["codeOnFailure"] = string.Template(