Bug 758415 - Copy expando objects during object transplanting. r=mrbkap

This commit is contained in:
Bobby Holley 2012-06-05 19:07:37 +02:00
parent f3bf0cee49
commit 59c1c5f462
3 changed files with 29 additions and 0 deletions

View File

@ -17,6 +17,7 @@
#include "jsproxy.h"
#include "AccessCheck.h"
#include "WrapperFactory.h"
#include "XrayWrapper.h"
#include "dombindings.h"
#include "nsContentUtils.h"
@ -1620,6 +1621,12 @@ XPCWrappedNative::ReparentWrapperIfFound(XPCCallContext& ccx,
if (!propertyHolder || !JS_CopyPropertiesFrom(ccx, propertyHolder, flat))
return NS_ERROR_OUT_OF_MEMORY;
// Expandos from other compartments are attached to the target JS object.
// Copy them over, and let the old ones die a natural death.
SetExpandoChain(newobj, nsnull);
if (!XrayUtils::CloneExpandoChain(ccx, newobj, flat))
return NS_ERROR_FAILURE;
// Before proceeding, eagerly create any same-compartment security wrappers
// that the object might have. This forces us to take the 'WithWrapper' path
// while transplanting that handles this stuff correctly.

View File

@ -205,6 +205,26 @@ EnsureExpandoObject(JSContext *cx, JSObject *wrapper, JSObject *target)
return expandoObject;
}
bool
CloneExpandoChain(JSContext *cx, JSObject *dst, JSObject *src)
{
MOZ_ASSERT(js::IsObjectInContextCompartment(dst, cx));
MOZ_ASSERT(GetExpandoChain(dst) == nsnull);
JSObject *oldHead = GetExpandoChain(src);
while (oldHead) {
JSObject *exclusive = JS_GetReservedSlot(oldHead,
JSSLOT_EXPANDO_EXCLUSIVE_GLOBAL)
.toObjectOrNull();
JSObject *newHead =
AttachExpandoObject(cx, dst, GetExpandoObjectPrincipal(oldHead), exclusive);
if (!JS_CopyPropertiesFrom(cx, newHead, oldHead))
return false;
oldHead = JS_GetReservedSlot(oldHead, JSSLOT_EXPANDO_NEXT).toObjectOrNull();
}
return true;
}
JSObject *
createHolder(JSContext *cx, JSObject *wrappedNative, JSObject *parent)
{

View File

@ -27,6 +27,8 @@ namespace XrayUtils {
extern JSClass HolderClass;
bool CloneExpandoChain(JSContext *cx, JSObject *src, JSObject *dst);
JSObject *createHolder(JSContext *cx, JSObject *wrappedNative, JSObject *parent);
bool