зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1371259 part 3. Change UnwrapObject<> and the UNWRAP_OBJECT macro to allow passing in mutable object or value handles for the thing being unwrapped, and do so at various callsites. r=peterv
I did audit all UNWRAP_OBJECT callers to make sure that the lifetimes of all the temporary Rooted or the RefPtrs they unwrap into are long enough.
This commit is contained in:
Родитель
5fd161c633
Коммит
5c76874a46
|
@ -446,10 +446,12 @@ StructuredCloneHolder::WriteFullySerializableObjects(JSContext* aCx,
|
|||
JSStructuredCloneWriter* aWriter,
|
||||
JS::Handle<JSObject*> aObj)
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(aCx, aObj);
|
||||
|
||||
// See if this is a ImageData object.
|
||||
{
|
||||
ImageData* imageData = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(ImageData, aObj, imageData))) {
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(ImageData, &obj, imageData))) {
|
||||
return WriteStructuredCloneImageData(aCx, aWriter, imageData);
|
||||
}
|
||||
}
|
||||
|
@ -457,7 +459,7 @@ StructuredCloneHolder::WriteFullySerializableObjects(JSContext* aCx,
|
|||
// Handle URLSearchParams cloning
|
||||
{
|
||||
URLSearchParams* usp = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(URLSearchParams, aObj, usp))) {
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(URLSearchParams, &obj, usp))) {
|
||||
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_URLSEARCHPARAMS, 0) &&
|
||||
usp->WriteStructuredClone(aWriter);
|
||||
}
|
||||
|
@ -466,7 +468,7 @@ StructuredCloneHolder::WriteFullySerializableObjects(JSContext* aCx,
|
|||
// Handle Key cloning
|
||||
{
|
||||
CryptoKey* key = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(CryptoKey, aObj, key))) {
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(CryptoKey, &obj, key))) {
|
||||
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_WEBCRYPTO_KEY, 0) &&
|
||||
key->WriteStructuredClone(aWriter);
|
||||
}
|
||||
|
@ -476,7 +478,7 @@ StructuredCloneHolder::WriteFullySerializableObjects(JSContext* aCx,
|
|||
{
|
||||
// Handle WebRTC Certificate cloning
|
||||
RTCCertificate* cert = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(RTCCertificate, aObj, cert))) {
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(RTCCertificate, &obj, cert))) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_RTC_CERTIFICATE, 0) &&
|
||||
cert->WriteStructuredClone(aWriter);
|
||||
|
@ -484,8 +486,8 @@ StructuredCloneHolder::WriteFullySerializableObjects(JSContext* aCx,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (NS_IsMainThread() && xpc::IsReflector(aObj)) {
|
||||
nsCOMPtr<nsISupports> base = xpc::UnwrapReflectorToISupports(aObj);
|
||||
if (NS_IsMainThread() && xpc::IsReflector(obj)) {
|
||||
nsCOMPtr<nsISupports> base = xpc::UnwrapReflectorToISupports(obj);
|
||||
nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(base);
|
||||
if (principal) {
|
||||
auto nsjsprincipals = nsJSPrincipals::get(principal);
|
||||
|
@ -1011,10 +1013,12 @@ StructuredCloneHolder::CustomWriteHandler(JSContext* aCx,
|
|||
return false;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> obj(aCx, aObj);
|
||||
|
||||
// See if this is a File/Blob object.
|
||||
{
|
||||
Blob* blob = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, aObj, blob))) {
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, &obj, blob))) {
|
||||
return WriteBlob(aWriter, blob, this);
|
||||
}
|
||||
}
|
||||
|
@ -1022,7 +1026,7 @@ StructuredCloneHolder::CustomWriteHandler(JSContext* aCx,
|
|||
// See if this is a Directory object.
|
||||
{
|
||||
Directory* directory = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Directory, aObj, directory))) {
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Directory, &obj, directory))) {
|
||||
return WriteDirectory(aWriter, directory);
|
||||
}
|
||||
}
|
||||
|
@ -1030,7 +1034,7 @@ StructuredCloneHolder::CustomWriteHandler(JSContext* aCx,
|
|||
// See if this is a FileList object.
|
||||
{
|
||||
FileList* fileList = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(FileList, aObj, fileList))) {
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(FileList, &obj, fileList))) {
|
||||
return WriteFileList(aWriter, fileList, this);
|
||||
}
|
||||
}
|
||||
|
@ -1038,7 +1042,7 @@ StructuredCloneHolder::CustomWriteHandler(JSContext* aCx,
|
|||
// See if this is a FormData object.
|
||||
{
|
||||
FormData* formData = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(FormData, aObj, formData))) {
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(FormData, &obj, formData))) {
|
||||
return WriteFormData(aWriter, formData, this);
|
||||
}
|
||||
}
|
||||
|
@ -1047,7 +1051,7 @@ StructuredCloneHolder::CustomWriteHandler(JSContext* aCx,
|
|||
if (mStructuredCloneScope == StructuredCloneScope::SameProcessSameThread ||
|
||||
mStructuredCloneScope == StructuredCloneScope::SameProcessDifferentThread) {
|
||||
ImageBitmap* imageBitmap = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(ImageBitmap, aObj, imageBitmap))) {
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(ImageBitmap, &obj, imageBitmap))) {
|
||||
return ImageBitmap::WriteStructuredClone(aWriter,
|
||||
GetSurfaces(),
|
||||
imageBitmap);
|
||||
|
@ -1057,7 +1061,7 @@ StructuredCloneHolder::CustomWriteHandler(JSContext* aCx,
|
|||
// See if this is a StructuredCloneBlob object.
|
||||
{
|
||||
StructuredCloneBlob* holder = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(StructuredCloneHolder, aObj, holder))) {
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(StructuredCloneHolder, &obj, holder))) {
|
||||
return holder->WriteStructuredClone(aCx, aWriter, this);
|
||||
}
|
||||
}
|
||||
|
@ -1065,8 +1069,8 @@ StructuredCloneHolder::CustomWriteHandler(JSContext* aCx,
|
|||
// See if this is a WasmModule.
|
||||
if ((mStructuredCloneScope == StructuredCloneScope::SameProcessSameThread ||
|
||||
mStructuredCloneScope == StructuredCloneScope::SameProcessDifferentThread) &&
|
||||
JS::IsWasmModuleObject(aObj)) {
|
||||
RefPtr<JS::WasmModule> module = JS::GetWasmModule(aObj);
|
||||
JS::IsWasmModuleObject(obj)) {
|
||||
RefPtr<JS::WasmModule> module = JS::GetWasmModule(obj);
|
||||
MOZ_ASSERT(module);
|
||||
|
||||
return WriteWasmModule(aWriter, module, this);
|
||||
|
@ -1174,9 +1178,11 @@ StructuredCloneHolder::CustomWriteTransferHandler(JSContext* aCx,
|
|||
return false;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> obj(aCx, aObj);
|
||||
|
||||
{
|
||||
MessagePort* port = nullptr;
|
||||
nsresult rv = UNWRAP_OBJECT(MessagePort, aObj, port);
|
||||
nsresult rv = UNWRAP_OBJECT(MessagePort, &obj, port);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// We use aExtraData to store the index of this new port identifier.
|
||||
*aExtraData = mPortIdentifiers.Length();
|
||||
|
@ -1194,7 +1200,7 @@ StructuredCloneHolder::CustomWriteTransferHandler(JSContext* aCx,
|
|||
if (mStructuredCloneScope == StructuredCloneScope::SameProcessSameThread ||
|
||||
mStructuredCloneScope == StructuredCloneScope::SameProcessDifferentThread) {
|
||||
OffscreenCanvas* canvas = nullptr;
|
||||
rv = UNWRAP_OBJECT(OffscreenCanvas, aObj, canvas);
|
||||
rv = UNWRAP_OBJECT(OffscreenCanvas, &obj, canvas);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
MOZ_ASSERT(canvas);
|
||||
|
||||
|
@ -1209,7 +1215,7 @@ StructuredCloneHolder::CustomWriteTransferHandler(JSContext* aCx,
|
|||
}
|
||||
|
||||
ImageBitmap* bitmap = nullptr;
|
||||
rv = UNWRAP_OBJECT(ImageBitmap, aObj, bitmap);
|
||||
rv = UNWRAP_OBJECT(ImageBitmap, &obj, bitmap);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
MOZ_ASSERT(bitmap);
|
||||
|
||||
|
|
|
@ -3227,16 +3227,16 @@ nsDOMWindowUtils::GetFileId(JS::Handle<JS::Value> aFile, JSContext* aCx,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
JSObject* obj = aFile.toObjectOrNull();
|
||||
JS::Rooted<JSObject*> obj(aCx, aFile.toObjectOrNull());
|
||||
|
||||
IDBMutableFile* mutableFile = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(IDBMutableFile, obj, mutableFile))) {
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(IDBMutableFile, &obj, mutableFile))) {
|
||||
*_retval = mutableFile->GetFileId();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Blob* blob = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, obj, blob))) {
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, &obj, blob))) {
|
||||
*_retval = blob->GetFileId();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -3254,10 +3254,10 @@ nsDOMWindowUtils::GetFilePath(JS::HandleValue aFile, JSContext* aCx,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
JSObject* obj = aFile.toObjectOrNull();
|
||||
JS::Rooted<JSObject*> obj(aCx, aFile.toObjectOrNull());
|
||||
|
||||
File* file = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(File, obj, file))) {
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(File, &obj, file))) {
|
||||
nsString filePath;
|
||||
ErrorResult rv;
|
||||
file->GetMozFullPathInternal(filePath, rv);
|
||||
|
|
|
@ -1716,9 +1716,10 @@ XrayResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
|||
// be protected by read-only/non-configurable properties, and any functions
|
||||
// we end up with should _always_ be living in our own scope (the XBL scope).
|
||||
// Make sure to assert that.
|
||||
JS::Rooted<JSObject*> maybeElement(cx, obj);
|
||||
Element* element;
|
||||
if (xpc::ObjectScope(wrapper)->IsContentXBLScope() &&
|
||||
NS_SUCCEEDED(UNWRAP_OBJECT(Element, obj, element))) {
|
||||
NS_SUCCEEDED(UNWRAP_OBJECT(Element, &maybeElement, element))) {
|
||||
if (!nsContentUtils::LookupBindingMember(cx, element, id, desc)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2306,14 +2307,15 @@ ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg)
|
|||
}
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> maybeObjLC(aCx, aObj);
|
||||
nsObjectLoadingContent* htmlobject;
|
||||
nsresult rv = UNWRAP_OBJECT(HTMLObjectElement, aObj, htmlobject);
|
||||
nsresult rv = UNWRAP_OBJECT(HTMLObjectElement, &maybeObjLC, htmlobject);
|
||||
if (NS_FAILED(rv)) {
|
||||
rv = UnwrapObject<prototypes::id::HTMLEmbedElement,
|
||||
HTMLSharedObjectElement>(aObj, htmlobject);
|
||||
HTMLSharedObjectElement>(&maybeObjLC, htmlobject);
|
||||
if (NS_FAILED(rv)) {
|
||||
rv = UnwrapObject<prototypes::id::HTMLAppletElement,
|
||||
HTMLSharedObjectElement>(aObj, htmlobject);
|
||||
HTMLSharedObjectElement>(&maybeObjLC, htmlobject);
|
||||
if (NS_FAILED(rv)) {
|
||||
htmlobject = nullptr;
|
||||
}
|
||||
|
@ -2903,9 +2905,16 @@ GenericBindingGetter(JSContext* cx, unsigned argc, JS::Value* vp)
|
|||
}
|
||||
JS::Rooted<JSObject*> obj(cx, &args.thisv().toObject());
|
||||
|
||||
// NOTE: we want to leave obj in its initial compartment, so don't want to
|
||||
// pass it to UnwrapObject.
|
||||
JS::Rooted<JSObject*> rootSelf(cx, obj);
|
||||
void* self;
|
||||
{
|
||||
nsresult rv = UnwrapObject<void>(obj, self, protoID, info->depth);
|
||||
binding_detail::MutableObjectHandleWrapper wrapper(&rootSelf);
|
||||
nsresult rv = binding_detail::UnwrapObjectInternal<void, true>(wrapper,
|
||||
self,
|
||||
protoID,
|
||||
info->depth);
|
||||
if (NS_FAILED(rv)) {
|
||||
return ThrowInvalidThis(cx, args,
|
||||
rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO,
|
||||
|
@ -2942,9 +2951,16 @@ GenericPromiseReturningBindingGetter(JSContext* cx, unsigned argc, JS::Value* vp
|
|||
}
|
||||
JS::Rooted<JSObject*> obj(cx, &args.thisv().toObject());
|
||||
|
||||
// NOTE: we want to leave obj in its initial compartment, so don't want to
|
||||
// pass it to UnwrapObject.
|
||||
JS::Rooted<JSObject*> rootSelf(cx, obj);
|
||||
void* self;
|
||||
{
|
||||
nsresult rv = UnwrapObject<void>(obj, self, protoID, info->depth);
|
||||
binding_detail::MutableObjectHandleWrapper wrapper(&rootSelf);
|
||||
nsresult rv = binding_detail::UnwrapObjectInternal<void, true>(wrapper,
|
||||
self,
|
||||
protoID,
|
||||
info->depth);
|
||||
if (NS_FAILED(rv)) {
|
||||
ThrowInvalidThis(cx, args, rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO,
|
||||
protoID);
|
||||
|
@ -2979,9 +2995,16 @@ GenericBindingSetter(JSContext* cx, unsigned argc, JS::Value* vp)
|
|||
}
|
||||
JS::Rooted<JSObject*> obj(cx, &args.thisv().toObject());
|
||||
|
||||
// NOTE: we want to leave obj in its initial compartment, so don't want to
|
||||
// pass it to UnwrapObject.
|
||||
JS::Rooted<JSObject*> rootSelf(cx, obj);
|
||||
void* self;
|
||||
{
|
||||
nsresult rv = UnwrapObject<void>(obj, self, protoID, info->depth);
|
||||
binding_detail::MutableObjectHandleWrapper wrapper(&rootSelf);
|
||||
nsresult rv = binding_detail::UnwrapObjectInternal<void, true>(wrapper,
|
||||
self,
|
||||
protoID,
|
||||
info->depth);
|
||||
if (NS_FAILED(rv)) {
|
||||
return ThrowInvalidThis(cx, args,
|
||||
rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO,
|
||||
|
@ -3014,9 +3037,16 @@ GenericBindingMethod(JSContext* cx, unsigned argc, JS::Value* vp)
|
|||
}
|
||||
JS::Rooted<JSObject*> obj(cx, &args.thisv().toObject());
|
||||
|
||||
// NOTE: we want to leave obj in its initial compartment, so don't want to
|
||||
// pass it to UnwrapObject.
|
||||
JS::Rooted<JSObject*> rootSelf(cx, obj);
|
||||
void* self;
|
||||
{
|
||||
nsresult rv = UnwrapObject<void>(obj, self, protoID, info->depth);
|
||||
binding_detail::MutableObjectHandleWrapper wrapper(&rootSelf);
|
||||
nsresult rv = binding_detail::UnwrapObjectInternal<void, true>(wrapper,
|
||||
self,
|
||||
protoID,
|
||||
info->depth);
|
||||
if (NS_FAILED(rv)) {
|
||||
return ThrowInvalidThis(cx, args,
|
||||
rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO,
|
||||
|
@ -3052,9 +3082,16 @@ GenericPromiseReturningBindingMethod(JSContext* cx, unsigned argc, JS::Value* vp
|
|||
}
|
||||
JS::Rooted<JSObject*> obj(cx, &args.thisv().toObject());
|
||||
|
||||
// NOTE: we want to leave obj in its initial compartment, so don't want to
|
||||
// pass it to UnwrapObject.
|
||||
JS::Rooted<JSObject*> rootSelf(cx, obj);
|
||||
void* self;
|
||||
{
|
||||
nsresult rv = UnwrapObject<void>(obj, self, protoID, info->depth);
|
||||
binding_detail::MutableObjectHandleWrapper wrapper(&rootSelf);
|
||||
nsresult rv = binding_detail::UnwrapObjectInternal<void, true>(wrapper,
|
||||
self,
|
||||
protoID,
|
||||
info->depth);
|
||||
if (NS_FAILED(rv)) {
|
||||
ThrowInvalidThis(cx, args, rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO,
|
||||
protoID);
|
||||
|
|
|
@ -186,45 +186,86 @@ IsDOMObject(JSObject* obj)
|
|||
return IsDOMClass(js::GetObjectClass(obj));
|
||||
}
|
||||
|
||||
// There are two valid ways to use UNWRAP_OBJECT: Either obj needs to
|
||||
// be a MutableHandle<JSObject*>, or value needs to be a strong-reference
|
||||
// smart pointer type (OwningNonNull or RefPtr or nsCOMPtr), in which case obj
|
||||
// can be anything that converts to JSObject*.
|
||||
#define UNWRAP_OBJECT(Interface, obj, value) \
|
||||
mozilla::dom::UnwrapObject<mozilla::dom::prototypes::id::Interface, \
|
||||
mozilla::dom::Interface##Binding::NativeType>(obj, value)
|
||||
|
||||
// Test whether the given object is an instance of the given interface.
|
||||
#define IS_INSTANCE_OF(Interface, obj) \
|
||||
mozilla::dom::IsInstanceOf<mozilla::dom::prototypes::id::Interface, \
|
||||
mozilla::dom::Interface##Binding::NativeType>(obj)
|
||||
|
||||
// Unwrap the given non-wrapper object. This can be used with any obj that
|
||||
// converts to JSObject*; as long as that JSObject* is live the return value
|
||||
// will be valid.
|
||||
#define UNWRAP_NON_WRAPPER_OBJECT(Interface, obj, value) \
|
||||
mozilla::dom::UnwrapNonWrapperObject<mozilla::dom::prototypes::id::Interface, \
|
||||
mozilla::dom::Interface##Binding::NativeType>(obj, value)
|
||||
|
||||
// Some callers don't want to set an exception when unwrapping fails
|
||||
// (for example, overload resolution uses unwrapping to tell what sort
|
||||
// of thing it's looking at).
|
||||
// U must be something that a T* can be assigned to (e.g. T* or an RefPtr<T>).
|
||||
template <class T, typename U>
|
||||
//
|
||||
// The obj argument will be mutated to point to CheckedUnwrap of itself if the
|
||||
// passed-in value is not a DOM object and CheckedUnwrap succeeds.
|
||||
//
|
||||
// If mayBeWrapper is true, there are three valid ways to invoke
|
||||
// UnwrapObjectInternal: Either obj needs to be a class wrapping a
|
||||
// MutableHandle<JSObject*>, with an assignment operator that sets the handle to
|
||||
// the given object, or U needs to be a strong-reference smart pointer type
|
||||
// (OwningNonNull or RefPtr or nsCOMPtr), or the value being stored in "value"
|
||||
// must not escape past being tested for falsiness immediately after the
|
||||
// UnwrapObjectInternal call.
|
||||
//
|
||||
// If mayBeWrapper is false, obj can just be a JSObject*, and U anything that a
|
||||
// T* can be assigned to.
|
||||
namespace binding_detail {
|
||||
template <class T, bool mayBeWrapper, typename U, typename V>
|
||||
MOZ_ALWAYS_INLINE nsresult
|
||||
UnwrapObject(JSObject* obj, U& value, prototypes::ID protoID,
|
||||
uint32_t protoDepth)
|
||||
UnwrapObjectInternal(V& obj, U& value, prototypes::ID protoID,
|
||||
uint32_t protoDepth)
|
||||
{
|
||||
/* First check to see whether we have a DOM object */
|
||||
const DOMJSClass* domClass = GetDOMClass(obj);
|
||||
if (!domClass) {
|
||||
/* Maybe we have a security wrapper or outer window? */
|
||||
if (!js::IsWrapper(obj)) {
|
||||
/* Not a DOM object, not a wrapper, just bail */
|
||||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
}
|
||||
|
||||
obj = js::CheckedUnwrap(obj, /* stopAtWindowProxy = */ false);
|
||||
if (!obj) {
|
||||
return NS_ERROR_XPC_SECURITY_MANAGER_VETO;
|
||||
}
|
||||
MOZ_ASSERT(!js::IsWrapper(obj));
|
||||
domClass = GetDOMClass(obj);
|
||||
if (!domClass) {
|
||||
/* We don't have a DOM object */
|
||||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
if (domClass) {
|
||||
/* This object is a DOM object. Double-check that it is safely
|
||||
castable to T by checking whether it claims to inherit from the
|
||||
class identified by protoID. */
|
||||
if (domClass->mInterfaceChain[protoDepth] == protoID) {
|
||||
value = UnwrapDOMObject<T>(obj);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* This object is a DOM object. Double-check that it is safely
|
||||
castable to T by checking whether it claims to inherit from the
|
||||
class identified by protoID. */
|
||||
if (domClass->mInterfaceChain[protoDepth] == protoID) {
|
||||
value = UnwrapDOMObject<T>(obj);
|
||||
/* Maybe we have a security wrapper or outer window? */
|
||||
if (!mayBeWrapper || !js::IsWrapper(obj)) {
|
||||
/* Not a DOM object, not a wrapper, just bail */
|
||||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
}
|
||||
|
||||
JSObject* unwrappedObj =
|
||||
js::CheckedUnwrap(obj, /* stopAtWindowProxy = */ false);
|
||||
if (!unwrappedObj) {
|
||||
return NS_ERROR_XPC_SECURITY_MANAGER_VETO;
|
||||
}
|
||||
MOZ_ASSERT(!js::IsWrapper(unwrappedObj));
|
||||
// Recursive call is OK, because now we're using false for mayBeWrapper and
|
||||
// we never reach this code if that boolean is false, so can't keep calling
|
||||
// ourselves.
|
||||
nsresult rv = UnwrapObjectInternal<T, false>(unwrappedObj, value,
|
||||
protoID, protoDepth);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// It's very important to not update "obj" with the "unwrappedObj" value
|
||||
// until we know the unwrap has succeeded. Otherwise, in a situation in
|
||||
// which we have an overload of object and primitive we could end up
|
||||
// converting to the primitive from the unwrappedObj, whereas we want to do
|
||||
// it from the original object.
|
||||
obj = unwrappedObj;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -232,12 +273,121 @@ UnwrapObject(JSObject* obj, U& value, prototypes::ID protoID,
|
|||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
}
|
||||
|
||||
template <prototypes::ID PrototypeID, class T, typename U>
|
||||
struct MutableObjectHandleWrapper {
|
||||
explicit MutableObjectHandleWrapper(JS::MutableHandle<JSObject*> aHandle)
|
||||
: mHandle(aHandle)
|
||||
{
|
||||
}
|
||||
|
||||
void operator=(JSObject* aObject)
|
||||
{
|
||||
MOZ_ASSERT(aObject);
|
||||
mHandle.set(aObject);
|
||||
}
|
||||
|
||||
operator JSObject*() const
|
||||
{
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
private:
|
||||
JS::MutableHandle<JSObject*> mHandle;
|
||||
};
|
||||
|
||||
struct MutableValueHandleWrapper {
|
||||
explicit MutableValueHandleWrapper(JS::MutableHandle<JS::Value> aHandle)
|
||||
: mHandle(aHandle)
|
||||
{
|
||||
}
|
||||
|
||||
void operator=(JSObject* aObject)
|
||||
{
|
||||
MOZ_ASSERT(aObject);
|
||||
mHandle.setObject(*aObject);
|
||||
}
|
||||
|
||||
operator JSObject*() const
|
||||
{
|
||||
return &mHandle.toObject();
|
||||
}
|
||||
|
||||
private:
|
||||
JS::MutableHandle<JS::Value> mHandle;
|
||||
};
|
||||
|
||||
} // namespace binding_detail
|
||||
|
||||
// UnwrapObject overloads that ensure we have a MutableHandle to keep it alive.
|
||||
template<prototypes::ID PrototypeID, class T, typename U>
|
||||
MOZ_ALWAYS_INLINE nsresult
|
||||
UnwrapObject(JSObject* obj, U& value)
|
||||
UnwrapObject(JS::MutableHandle<JSObject*> obj, U& value)
|
||||
{
|
||||
return UnwrapObject<T>(obj, value, PrototypeID,
|
||||
PrototypeTraits<PrototypeID>::Depth);
|
||||
binding_detail::MutableObjectHandleWrapper wrapper(obj);
|
||||
return binding_detail::UnwrapObjectInternal<T, true>(
|
||||
wrapper, value, PrototypeID, PrototypeTraits<PrototypeID>::Depth);
|
||||
}
|
||||
|
||||
template<prototypes::ID PrototypeID, class T, typename U>
|
||||
MOZ_ALWAYS_INLINE nsresult
|
||||
UnwrapObject(JS::MutableHandle<JS::Value> obj, U& value)
|
||||
{
|
||||
MOZ_ASSERT(obj.isObject());
|
||||
binding_detail::MutableValueHandleWrapper wrapper(obj);
|
||||
return binding_detail::UnwrapObjectInternal<T, true>(
|
||||
wrapper, value, PrototypeID, PrototypeTraits<PrototypeID>::Depth);
|
||||
}
|
||||
|
||||
// UnwrapObject overloads that ensure we have a strong ref to keep it alive.
|
||||
template<prototypes::ID PrototypeID, class T, typename U>
|
||||
MOZ_ALWAYS_INLINE nsresult
|
||||
UnwrapObject(JSObject* obj, RefPtr<U>& value)
|
||||
{
|
||||
return binding_detail::UnwrapObjectInternal<T, true>(
|
||||
obj, value, PrototypeID, PrototypeTraits<PrototypeID>::Depth);
|
||||
}
|
||||
|
||||
template<prototypes::ID PrototypeID, class T, typename U>
|
||||
MOZ_ALWAYS_INLINE nsresult
|
||||
UnwrapObject(JSObject* obj, nsCOMPtr<U>& value)
|
||||
{
|
||||
return binding_detail::UnwrapObjectInternal<T, true>(
|
||||
obj, value, PrototypeID, PrototypeTraits<PrototypeID>::Depth);
|
||||
}
|
||||
|
||||
template<prototypes::ID PrototypeID, class T, typename U>
|
||||
MOZ_ALWAYS_INLINE nsresult
|
||||
UnwrapObject(JSObject* obj, OwningNonNull<U>& value)
|
||||
{
|
||||
return binding_detail::UnwrapObjectInternal<T, true>(
|
||||
obj, value, PrototypeID, PrototypeTraits<PrototypeID>::Depth);
|
||||
}
|
||||
|
||||
// An UnwrapObject overload that just calls one of the JSObject* ones.
|
||||
template<prototypes::ID PrototypeID, class T, typename U>
|
||||
MOZ_ALWAYS_INLINE nsresult
|
||||
UnwrapObject(JS::Handle<JS::Value> obj, U& value)
|
||||
{
|
||||
MOZ_ASSERT(obj.isObject());
|
||||
return UnwrapObject<PrototypeID, T>(&obj.toObject(), value);
|
||||
}
|
||||
|
||||
template<prototypes::ID PrototypeID, class T>
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
IsInstanceOf(JSObject* obj)
|
||||
{
|
||||
void* ignored;
|
||||
nsresult unwrapped = binding_detail::UnwrapObjectInternal<T, true>(
|
||||
obj, ignored, PrototypeID, PrototypeTraits<PrototypeID>::Depth);
|
||||
return NS_SUCCEEDED(unwrapped);
|
||||
}
|
||||
|
||||
template<prototypes::ID PrototypeID, class T, typename U>
|
||||
MOZ_ALWAYS_INLINE nsresult
|
||||
UnwrapNonWrapperObject(JSObject* obj, U& value)
|
||||
{
|
||||
MOZ_ASSERT(!js::IsWrapper(obj));
|
||||
return binding_detail::UnwrapObjectInternal<T, false>(
|
||||
obj, value, PrototypeID, PrototypeTraits<PrototypeID>::Depth);
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
|
|
|
@ -4353,18 +4353,16 @@ class CastableObjectUnwrapper():
|
|||
$*{codeOnFailure}
|
||||
}
|
||||
}
|
||||
JS::Rooted<JS::Value> maybeUncheckedVal(cx, JS::ObjectValue(*maybeUncheckedObj));
|
||||
""",
|
||||
codeOnFailure=(codeOnFailure % { 'securityError': 'true'}))
|
||||
self.substitution["source"] = "maybeUncheckedVal"
|
||||
self.substitution["mutableSource"] = "&maybeUncheckedVal"
|
||||
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.
|
||||
JS::Rooted<JSObject*> source(cx, &${source}.toObject());
|
||||
JSAutoCompartment ac(cx, source);
|
||||
rv = UnwrapArg<${type}>(cx, source, getter_AddRefs(objPtr));
|
||||
JSAutoCompartment ac(cx, ${source});
|
||||
rv = UnwrapArg<${type}>(cx, ${source}, getter_AddRefs(objPtr));
|
||||
}
|
||||
""")
|
||||
else:
|
||||
|
@ -4425,7 +4423,7 @@ class CastableObjectUnwrapper():
|
|||
$*{uncheckedObjDecl}
|
||||
{
|
||||
$*{uncheckedObjGet}
|
||||
nsresult rv = UnwrapObject<${protoID}, ${type}>(&${source}.toObject(), ${target});
|
||||
nsresult rv = UnwrapObject<${protoID}, ${type}>(${mutableSource}, ${target});
|
||||
if (NS_FAILED(rv)) {
|
||||
$*{codeOnFailure}
|
||||
}
|
||||
|
|
|
@ -219,8 +219,14 @@ WebIDLGlobalNameHash::DefineIfEnabled(JSContext* aCx,
|
|||
}
|
||||
|
||||
{
|
||||
// It's safe to pass "&global" here, because we've already unwrapped it, but
|
||||
// for general sanity better to not have debug code even having the
|
||||
// appearance of mutating things that opt code uses.
|
||||
#ifdef DEBUG
|
||||
JS::Rooted<JSObject*> temp(aCx, global);
|
||||
DebugOnly<nsGlobalWindow*> win;
|
||||
MOZ_ASSERT(NS_SUCCEEDED(UNWRAP_OBJECT(Window, global, win)));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(UNWRAP_OBJECT(Window, &temp, win)));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (checkEnabledForScope && !checkEnabledForScope(aCx, global)) {
|
||||
|
|
|
@ -211,8 +211,11 @@ StructuredCloneWriteCallback(JSContext* aCx,
|
|||
return JS_WriteBytes(aWriter, &value, sizeof(value));
|
||||
}
|
||||
|
||||
// UNWRAP_OBJECT calls might mutate this.
|
||||
JS::Rooted<JSObject*> obj(aCx, aObj);
|
||||
|
||||
IDBMutableFile* mutableFile;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(IDBMutableFile, aObj, mutableFile))) {
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(IDBMutableFile, &obj, mutableFile))) {
|
||||
if (cloneWriteInfo->mDatabase->IsFileHandleDisabled()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -281,7 +284,7 @@ StructuredCloneWriteCallback(JSContext* aCx,
|
|||
|
||||
{
|
||||
Blob* blob = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, aObj, blob))) {
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, &obj, blob))) {
|
||||
ErrorResult rv;
|
||||
uint64_t size = blob->GetSize(rv);
|
||||
MOZ_ASSERT(!rv.Failed());
|
||||
|
|
|
@ -157,8 +157,9 @@ WebVTTListener::OnCue(JS::Handle<JS::Value> aCue, JSContext* aCx)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> obj(aCx, &aCue.toObject());
|
||||
TextTrackCue* cue = nullptr;
|
||||
nsresult rv = UNWRAP_OBJECT(VTTCue, &aCue.toObject(), cue);
|
||||
nsresult rv = UNWRAP_OBJECT(VTTCue, &obj, cue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
cue->SetTrackElement(mElement);
|
||||
|
|
|
@ -403,13 +403,13 @@ MessagePort::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
|||
// Here we want to check if the transerable object list contains
|
||||
// this port.
|
||||
for (uint32_t i = 0; i < aTransferable.Length(); ++i) {
|
||||
JSObject* object = aTransferable[i];
|
||||
JS::Rooted<JSObject*> object(aCx, aTransferable[i]);
|
||||
if (!object) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MessagePort* port = nullptr;
|
||||
nsresult rv = UNWRAP_OBJECT(MessagePort, object, port);
|
||||
nsresult rv = UNWRAP_OBJECT(MessagePort, &object, port);
|
||||
if (NS_SUCCEEDED(rv) && port == this) {
|
||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return;
|
||||
|
|
|
@ -989,7 +989,7 @@ Notification::Constructor(const GlobalObject& aGlobal,
|
|||
ErrorResult& aRv)
|
||||
{
|
||||
// FIXME(nsm): If the sticky flag is set, throw an error.
|
||||
ServiceWorkerGlobalScope* scope = nullptr;
|
||||
RefPtr<ServiceWorkerGlobalScope> scope;
|
||||
UNWRAP_OBJECT(ServiceWorkerGlobalScope, aGlobal.Get(), scope);
|
||||
if (scope) {
|
||||
aRv.ThrowTypeError<MSG_NOTIFICATION_NO_CONSTRUCTOR_IN_SERVICEWORKER>();
|
||||
|
|
|
@ -1611,7 +1611,7 @@ PresentationPresentingInfo::ResolvedCallback(JSContext* aCx,
|
|||
// Start to listen to document state change event |STATE_TRANSFERRING|.
|
||||
// Use Element to support both HTMLIFrameElement and nsXULElement.
|
||||
Element* frame = nullptr;
|
||||
nsresult rv = UNWRAP_OBJECT(Element, obj, frame);
|
||||
nsresult rv = UNWRAP_OBJECT(Element, &obj, frame);
|
||||
if (NS_WARN_IF(!frame)) {
|
||||
ReplyError(NS_ERROR_DOM_OPERATION_ERR);
|
||||
return;
|
||||
|
|
|
@ -284,14 +284,13 @@ NativeHandlerCallback(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
|
|||
{
|
||||
JS::CallArgs args = CallArgsFromVp(aArgc, aVp);
|
||||
|
||||
JS::Rooted<JS::Value> v(aCx,
|
||||
js::GetFunctionNativeReserved(&args.callee(),
|
||||
SLOT_NATIVEHANDLER));
|
||||
JS::Value v = js::GetFunctionNativeReserved(&args.callee(),
|
||||
SLOT_NATIVEHANDLER);
|
||||
MOZ_ASSERT(v.isObject());
|
||||
|
||||
JS::Rooted<JSObject*> obj(aCx, &v.toObject());
|
||||
PromiseNativeHandler* handler = nullptr;
|
||||
if (NS_FAILED(UNWRAP_OBJECT(PromiseNativeHandler, &v.toObject(),
|
||||
handler))) {
|
||||
if (NS_FAILED(UNWRAP_OBJECT(PromiseNativeHandler, &obj, handler))) {
|
||||
return Throw(aCx, NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
|
||||
|
|
|
@ -1525,7 +1525,7 @@ CacheCreator::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
|||
|
||||
JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
|
||||
Cache* cache = nullptr;
|
||||
nsresult rv = UNWRAP_OBJECT(Cache, obj, cache);
|
||||
nsresult rv = UNWRAP_OBJECT(Cache, &obj, cache);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
FailLoaders(NS_ERROR_FAILURE);
|
||||
return;
|
||||
|
@ -1671,7 +1671,7 @@ CacheScriptLoader::ResolvedCallback(JSContext* aCx,
|
|||
|
||||
JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
|
||||
mozilla::dom::Response* response = nullptr;
|
||||
rv = UNWRAP_OBJECT(Response, obj, response);
|
||||
rv = UNWRAP_OBJECT(Response, &obj, response);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
Fail(rv);
|
||||
return;
|
||||
|
|
|
@ -35,9 +35,7 @@ ServiceWorkerVisible(JSContext* aCx, JSObject* aObj)
|
|||
return Preferences::GetBool("dom.serviceWorkers.enabled", false);
|
||||
}
|
||||
|
||||
ServiceWorkerGlobalScope* scope = nullptr;
|
||||
nsresult rv = UNWRAP_OBJECT(ServiceWorkerGlobalScope, aObj, scope);
|
||||
return NS_SUCCEEDED(rv);
|
||||
return IS_INSTANCE_OF(ServiceWorkerGlobalScope, aObj);
|
||||
}
|
||||
|
||||
ServiceWorker::ServiceWorker(nsPIDOMWindowInner* aWindow,
|
||||
|
|
|
@ -473,7 +473,7 @@ private:
|
|||
|
||||
Request* request;
|
||||
JS::Rooted<JSObject*> requestObj(aCx, &val.toObject());
|
||||
if (NS_WARN_IF(NS_FAILED(UNWRAP_OBJECT(Request, requestObj, request)))) {
|
||||
if (NS_WARN_IF(NS_FAILED(UNWRAP_OBJECT(Request, &requestObj, request)))) {
|
||||
return;
|
||||
};
|
||||
|
||||
|
@ -510,7 +510,7 @@ private:
|
|||
}
|
||||
|
||||
Cache* cache = nullptr;
|
||||
rv = UNWRAP_OBJECT(Cache, obj, cache);
|
||||
rv = UNWRAP_OBJECT(Cache, &obj, cache);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
@ -1124,7 +1124,7 @@ CompareCache::ManageValueResult(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
|||
}
|
||||
|
||||
Response* response = nullptr;
|
||||
nsresult rv = UNWRAP_OBJECT(Response, obj, response);
|
||||
nsresult rv = UNWRAP_OBJECT(Response, &obj, response);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
Finish(rv, false);
|
||||
return;
|
||||
|
|
|
@ -1050,11 +1050,11 @@ public:
|
|||
|
||||
if (aWorkerPrivate) {
|
||||
WorkerGlobalScope* globalScope = nullptr;
|
||||
UNWRAP_OBJECT(WorkerGlobalScope, global, globalScope);
|
||||
UNWRAP_OBJECT(WorkerGlobalScope, &global, globalScope);
|
||||
|
||||
if (!globalScope) {
|
||||
WorkerDebuggerGlobalScope* globalScope = nullptr;
|
||||
UNWRAP_OBJECT(WorkerDebuggerGlobalScope, global, globalScope);
|
||||
UNWRAP_OBJECT(WorkerDebuggerGlobalScope, &global, globalScope);
|
||||
|
||||
MOZ_ASSERT_IF(globalScope, globalScope->GetWrapperPreserveColor() == global);
|
||||
if (globalScope || IsDebuggerSandbox(global)) {
|
||||
|
@ -7112,8 +7112,9 @@ GetWorkerCrossThreadDispatcher(JSContext* aCx, const JS::Value& aWorker)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> obj(aCx, &aWorker.toObject());
|
||||
WorkerPrivate* w = nullptr;
|
||||
UNWRAP_OBJECT(Worker, &aWorker.toObject(), w);
|
||||
UNWRAP_OBJECT(Worker, &obj, w);
|
||||
MOZ_ASSERT(w);
|
||||
return w->GetCrossThreadDispatcher();
|
||||
}
|
||||
|
|
|
@ -1104,17 +1104,13 @@ BEGIN_WORKERS_NAMESPACE
|
|||
bool
|
||||
IsWorkerGlobal(JSObject* object)
|
||||
{
|
||||
nsIGlobalObject* globalObject = nullptr;
|
||||
return NS_SUCCEEDED(UNWRAP_OBJECT(WorkerGlobalScope, object,
|
||||
globalObject)) && !!globalObject;
|
||||
return IS_INSTANCE_OF(WorkerGlobalScope, object);
|
||||
}
|
||||
|
||||
bool
|
||||
IsDebuggerGlobal(JSObject* object)
|
||||
{
|
||||
nsIGlobalObject* globalObject = nullptr;
|
||||
return NS_SUCCEEDED(UNWRAP_OBJECT(WorkerDebuggerGlobalScope, object,
|
||||
globalObject)) && !!globalObject;
|
||||
return IS_INSTANCE_OF(WorkerDebuggerGlobalScope, object);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -415,8 +415,10 @@ nsXBLProtoImplField::InstallField(JS::Handle<JSObject*> aBoundNode,
|
|||
|
||||
JSAddonId* addonId = MapURIToAddonID(aBindingDocURI);
|
||||
|
||||
// Note: the UNWRAP_OBJECT may mutate boundNode; don't use it after that call.
|
||||
JS::Rooted<JSObject*> boundNode(jsapi.cx(), aBoundNode);
|
||||
Element* boundElement = nullptr;
|
||||
rv = UNWRAP_OBJECT(Element, aBoundNode, boundElement);
|
||||
rv = UNWRAP_OBJECT(Element, &boundNode, boundElement);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ XPathExpression::EvaluateWithContext(JSContext* aCx,
|
|||
JS::Handle<JSObject*> aInResult,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
XPathResult* inResult = nullptr;
|
||||
RefPtr<XPathResult> inResult;
|
||||
if (aInResult) {
|
||||
nsresult rv = UNWRAP_OBJECT(XPathResult, aInResult, inResult);
|
||||
if (NS_FAILED(rv) && rv != NS_ERROR_XPC_BAD_CONVERT_JS) {
|
||||
|
|
|
@ -150,8 +150,9 @@ public:
|
|||
JS::Handle<JSObject*> aObj)
|
||||
{
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(aCx, aObj);
|
||||
Blob* blob = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, aObj, blob))) {
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, &obj, blob))) {
|
||||
BlobImpl* blobImpl = blob->Impl();
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
|
|
|
@ -1708,12 +1708,10 @@ nsXPCComponents_Exception::HasInstance(nsIXPConnectWrappedNative* wrapper,
|
|||
{
|
||||
using namespace mozilla::dom;
|
||||
|
||||
RootedValue v(cx, val);
|
||||
if (bp) {
|
||||
Exception* e;
|
||||
*bp = (v.isObject() &&
|
||||
NS_SUCCEEDED(UNWRAP_OBJECT(Exception, &v.toObject(), e))) ||
|
||||
JSValIsInterfaceOfType(cx, v, NS_GET_IID(nsIException));
|
||||
*bp = (val.isObject() &&
|
||||
IS_INSTANCE_OF(Exception, &val.toObject())) ||
|
||||
JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIException));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2539,7 +2537,7 @@ nsXPCComponents_Utils::ImportGlobalProperties(HandleValue aPropertyList,
|
|||
|
||||
// Don't allow doing this if the global is a Window
|
||||
nsGlobalWindow* win;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Window, global, win))) {
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Window, &global, win))) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
|
|
|
@ -514,7 +514,7 @@ WindowOrNull(JSObject* aObj)
|
|||
MOZ_ASSERT(!js::IsWrapper(aObj));
|
||||
|
||||
nsGlobalWindow* win = nullptr;
|
||||
UNWRAP_OBJECT(Window, aObj, win);
|
||||
UNWRAP_NON_WRAPPER_OBJECT(Window, aObj, win);
|
||||
return win;
|
||||
}
|
||||
|
||||
|
|
|
@ -252,8 +252,9 @@ nsXPCWrappedJSClass::CallQueryInterfaceOnJSObject(JSContext* cx,
|
|||
if (jsexception.isObject()) {
|
||||
// XPConnect may have constructed an object to represent a
|
||||
// C++ QI failure. See if that is the case.
|
||||
JS::Rooted<JSObject*> exceptionObj(cx, &jsexception.toObject());
|
||||
Exception* e = nullptr;
|
||||
UNWRAP_OBJECT(Exception, &jsexception.toObject(), e);
|
||||
UNWRAP_OBJECT(Exception, &exceptionObj, e);
|
||||
|
||||
if (e &&
|
||||
NS_SUCCEEDED(e->GetResult(&rv)) &&
|
||||
|
|
Загрузка…
Ссылка в новой задаче