зеркало из https://github.com/mozilla/gecko-dev.git
Bug 869526 - GC: Fix more rooting hazards in xpconnect r=bholley
This commit is contained in:
Родитель
b287cc2cb5
Коммит
068a876f84
|
@ -1417,10 +1417,12 @@ nsXPCComponents_Results::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
|
|||
/* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, in uint32_t flags, out JSObjectPtr objp); */
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Results::NewResolve(nsIXPConnectWrappedNative *wrapper,
|
||||
JSContext * cx, JSObject * obj,
|
||||
jsid id, uint32_t flags,
|
||||
JSContext *cx, JSObject *objArg,
|
||||
jsid idArg, uint32_t flags,
|
||||
JSObject * *objp, bool *_retval)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
RootedId id(cx, idArg);
|
||||
JSAutoByteString name;
|
||||
|
||||
if (JSID_IS_STRING(id) && name.encodeLatin1(cx, JSID_TO_STRING(id))) {
|
||||
|
@ -4957,14 +4959,14 @@ JSBool
|
|||
nsXPCComponents::AttachComponentsObject(XPCCallContext& ccx,
|
||||
XPCWrappedNativeScope* aScope)
|
||||
{
|
||||
JSObject *components = aScope->GetComponentsJSObject(ccx);
|
||||
RootedObject components(ccx, aScope->GetComponentsJSObject(ccx));
|
||||
if (!components)
|
||||
return false;
|
||||
|
||||
JSObject *global = aScope->GetGlobalJSObject();
|
||||
RootedObject global(ccx, aScope->GetGlobalJSObject());
|
||||
MOZ_ASSERT(js::IsObjectInContextCompartment(global, ccx));
|
||||
|
||||
jsid id = ccx.GetRuntime()->GetStringID(XPCJSRuntime::IDX_COMPONENTS);
|
||||
RootedId id(ccx, ccx.GetRuntime()->GetStringID(XPCJSRuntime::IDX_COMPONENTS));
|
||||
JSPropertyOp getter = AccessCheck::isChrome(global) ? nullptr
|
||||
: &ContentComponentsGetterOp;
|
||||
return JS_DefinePropertyById(ccx, global, id, js::ObjectValue(*components),
|
||||
|
|
|
@ -213,11 +213,11 @@ GetMemberInfo(JSObject *obj, jsid memberId, const char **ifaceName)
|
|||
static void
|
||||
GetMethodInfo(JSContext *cx, jsval *vp, const char **ifaceNamep, jsid *memberIdp)
|
||||
{
|
||||
JSObject *funobj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
|
||||
RootedObject funobj(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
|
||||
NS_ASSERTION(JS_ObjectIsFunction(cx, funobj),
|
||||
"JSNative callee should be Function object");
|
||||
JSString *str = JS_GetFunctionId(JS_GetObjectFunction(funobj));
|
||||
jsid methodId = str ? INTERNED_STRING_TO_JSID(cx, str) : JSID_VOID;
|
||||
RootedString str(cx, JS_GetFunctionId(JS_GetObjectFunction(funobj)));
|
||||
RootedId methodId(cx, str ? INTERNED_STRING_TO_JSID(cx, str) : JSID_VOID);
|
||||
GetMemberInfo(JSVAL_TO_OBJECT(vp[1]), methodId, ifaceNamep);
|
||||
*memberIdp = methodId;
|
||||
}
|
||||
|
@ -361,8 +361,8 @@ void
|
|||
xpc_qsThrowBadArg(JSContext *cx, nsresult rv, jsval *vp, unsigned paramnum)
|
||||
{
|
||||
const char *ifaceName;
|
||||
jsid memberId;
|
||||
GetMethodInfo(cx, vp, &ifaceName, &memberId);
|
||||
RootedId memberId(cx);
|
||||
GetMethodInfo(cx, vp, &ifaceName, memberId.address());
|
||||
ThrowBadArg(cx, rv, ifaceName, memberId, NULL, paramnum);
|
||||
}
|
||||
|
||||
|
@ -381,8 +381,9 @@ xpc_qsThrowBadArgWithDetails(JSContext *cx, nsresult rv, unsigned paramnum,
|
|||
|
||||
void
|
||||
xpc_qsThrowBadSetterValue(JSContext *cx, nsresult rv,
|
||||
JSObject *obj, jsid propId)
|
||||
JSObject *obj, jsid propIdArg)
|
||||
{
|
||||
RootedId propId(cx, propIdArg);
|
||||
const char *ifaceName;
|
||||
GetMemberInfo(obj, propId, &ifaceName);
|
||||
ThrowBadArg(cx, rv, ifaceName, propId, NULL, 0);
|
||||
|
|
|
@ -416,14 +416,7 @@ XPCVariant::VariantDataToJS(XPCLazyCallContext& lccx,
|
|||
|
||||
// We ASSUME that the variant implementation can do these conversions...
|
||||
|
||||
nsXPTCVariant xpctvar;
|
||||
nsID iid;
|
||||
nsAutoString astring;
|
||||
nsAutoCString cString;
|
||||
nsUTF8String utf8String;
|
||||
uint32_t size;
|
||||
xpctvar.flags = 0;
|
||||
JSBool success;
|
||||
|
||||
NS_ABORT_IF_FALSE(js::IsObjectInContextCompartment(lccx.GetScopeForNewJSObjects(), cx),
|
||||
"bad scope for new JSObjects");
|
||||
|
@ -440,100 +433,134 @@ XPCVariant::VariantDataToJS(XPCLazyCallContext& lccx,
|
|||
case nsIDataType::VTYPE_FLOAT:
|
||||
case nsIDataType::VTYPE_DOUBLE:
|
||||
{
|
||||
// Easy. Handle inline.
|
||||
if (NS_FAILED(variant->GetAsDouble(&xpctvar.val.d)))
|
||||
double d;
|
||||
if (NS_FAILED(variant->GetAsDouble(&d)))
|
||||
return false;
|
||||
*pJSVal = JS_NumberValue(xpctvar.val.d);
|
||||
*pJSVal = JS_NumberValue(d);
|
||||
return true;
|
||||
}
|
||||
case nsIDataType::VTYPE_BOOL:
|
||||
{
|
||||
// Easy. Handle inline.
|
||||
if (NS_FAILED(variant->GetAsBool(&xpctvar.val.b)))
|
||||
bool b;
|
||||
if (NS_FAILED(variant->GetAsBool(&b)))
|
||||
return false;
|
||||
*pJSVal = BOOLEAN_TO_JSVAL(xpctvar.val.b);
|
||||
*pJSVal = BOOLEAN_TO_JSVAL(b);
|
||||
return true;
|
||||
}
|
||||
case nsIDataType::VTYPE_CHAR:
|
||||
if (NS_FAILED(variant->GetAsChar(&xpctvar.val.c)))
|
||||
{
|
||||
char c;
|
||||
if (NS_FAILED(variant->GetAsChar(&c)))
|
||||
return false;
|
||||
xpctvar.type = (uint8_t)TD_CHAR;
|
||||
break;
|
||||
return XPCConvert::NativeData2JS(lccx, pJSVal, (const void*)&c, TD_CHAR, &iid, pErr);
|
||||
}
|
||||
case nsIDataType::VTYPE_WCHAR:
|
||||
if (NS_FAILED(variant->GetAsWChar(&xpctvar.val.wc)))
|
||||
{
|
||||
PRUnichar wc;
|
||||
if (NS_FAILED(variant->GetAsWChar(&wc)))
|
||||
return false;
|
||||
xpctvar.type = (uint8_t)TD_WCHAR;
|
||||
break;
|
||||
return XPCConvert::NativeData2JS(lccx, pJSVal, (const void*)&wc, TD_WCHAR, &iid, pErr);
|
||||
}
|
||||
case nsIDataType::VTYPE_ID:
|
||||
{
|
||||
if (NS_FAILED(variant->GetAsID(&iid)))
|
||||
return false;
|
||||
xpctvar.type = (uint8_t)TD_PNSIID;
|
||||
xpctvar.val.p = &iid;
|
||||
break;
|
||||
nsID *v = &iid;
|
||||
return XPCConvert::NativeData2JS(lccx, pJSVal, (const void*)&v, TD_PNSIID, &iid, pErr);
|
||||
}
|
||||
case nsIDataType::VTYPE_ASTRING:
|
||||
{
|
||||
nsAutoString astring;
|
||||
if (NS_FAILED(variant->GetAsAString(astring)))
|
||||
return false;
|
||||
xpctvar.type = (uint8_t)TD_ASTRING;
|
||||
xpctvar.val.p = &astring;
|
||||
break;
|
||||
nsAutoString *v = &astring;
|
||||
return XPCConvert::NativeData2JS(lccx, pJSVal, (const void*)&v, TD_ASTRING, &iid, pErr);
|
||||
}
|
||||
case nsIDataType::VTYPE_DOMSTRING:
|
||||
{
|
||||
nsAutoString astring;
|
||||
if (NS_FAILED(variant->GetAsAString(astring)))
|
||||
return false;
|
||||
xpctvar.type = (uint8_t)TD_DOMSTRING;
|
||||
xpctvar.val.p = &astring;
|
||||
break;
|
||||
nsAutoString *v = &astring;
|
||||
return XPCConvert::NativeData2JS(lccx, pJSVal, (const void*)&v,
|
||||
TD_DOMSTRING, &iid, pErr);
|
||||
}
|
||||
case nsIDataType::VTYPE_CSTRING:
|
||||
{
|
||||
nsAutoCString cString;
|
||||
if (NS_FAILED(variant->GetAsACString(cString)))
|
||||
return false;
|
||||
xpctvar.type = (uint8_t)TD_CSTRING;
|
||||
xpctvar.val.p = &cString;
|
||||
break;
|
||||
nsAutoCString *v = &cString;
|
||||
return XPCConvert::NativeData2JS(lccx, pJSVal, (const void*)&v,
|
||||
TD_CSTRING, &iid, pErr);
|
||||
}
|
||||
case nsIDataType::VTYPE_UTF8STRING:
|
||||
{
|
||||
nsUTF8String utf8String;
|
||||
if (NS_FAILED(variant->GetAsAUTF8String(utf8String)))
|
||||
return false;
|
||||
xpctvar.type = (uint8_t)TD_UTF8STRING;
|
||||
xpctvar.val.p = &utf8String;
|
||||
break;
|
||||
nsUTF8String *v = &utf8String;
|
||||
return XPCConvert::NativeData2JS(lccx, pJSVal, (const void*)&v,
|
||||
TD_UTF8STRING, &iid, pErr);
|
||||
}
|
||||
case nsIDataType::VTYPE_CHAR_STR:
|
||||
if (NS_FAILED(variant->GetAsString((char**)&xpctvar.val.p)))
|
||||
{
|
||||
char *pc;
|
||||
if (NS_FAILED(variant->GetAsString(&pc)))
|
||||
return false;
|
||||
xpctvar.type = (uint8_t)TD_PSTRING;
|
||||
xpctvar.SetValNeedsCleanup();
|
||||
break;
|
||||
bool success = XPCConvert::NativeData2JS(lccx, pJSVal, (const void*)&pc,
|
||||
TD_PSTRING, &iid, pErr);
|
||||
nsMemory::Free(pc);
|
||||
return success;
|
||||
}
|
||||
case nsIDataType::VTYPE_STRING_SIZE_IS:
|
||||
if (NS_FAILED(variant->GetAsStringWithSize(&size,
|
||||
(char**)&xpctvar.val.p)))
|
||||
{
|
||||
char *pc;
|
||||
uint32_t size;
|
||||
if (NS_FAILED(variant->GetAsStringWithSize(&size, &pc)))
|
||||
return false;
|
||||
xpctvar.type = (uint8_t)TD_PSTRING_SIZE_IS;
|
||||
xpctvar.SetValNeedsCleanup();
|
||||
break;
|
||||
bool success = XPCConvert::NativeStringWithSize2JS(cx, pJSVal, (const void*)&pc,
|
||||
TD_PSTRING_SIZE_IS, size, pErr);
|
||||
nsMemory::Free(pc);
|
||||
return success;
|
||||
}
|
||||
case nsIDataType::VTYPE_WCHAR_STR:
|
||||
if (NS_FAILED(variant->GetAsWString((PRUnichar**)&xpctvar.val.p)))
|
||||
{
|
||||
PRUnichar *pwc;
|
||||
if (NS_FAILED(variant->GetAsWString(&pwc)))
|
||||
return false;
|
||||
xpctvar.type = (uint8_t)TD_PWSTRING;
|
||||
xpctvar.SetValNeedsCleanup();
|
||||
break;
|
||||
bool success = XPCConvert::NativeData2JS(lccx, pJSVal, (const void*)&pwc,
|
||||
TD_PSTRING, &iid, pErr);
|
||||
nsMemory::Free(pwc);
|
||||
return success;
|
||||
}
|
||||
case nsIDataType::VTYPE_WSTRING_SIZE_IS:
|
||||
if (NS_FAILED(variant->GetAsWStringWithSize(&size,
|
||||
(PRUnichar**)&xpctvar.val.p)))
|
||||
{
|
||||
PRUnichar *pwc;
|
||||
uint32_t size;
|
||||
if (NS_FAILED(variant->GetAsWStringWithSize(&size, &pwc)))
|
||||
return false;
|
||||
xpctvar.type = (uint8_t)TD_PWSTRING_SIZE_IS;
|
||||
xpctvar.SetValNeedsCleanup();
|
||||
break;
|
||||
bool success = XPCConvert::NativeStringWithSize2JS(cx, pJSVal, (const void*)&pwc,
|
||||
TD_PWSTRING_SIZE_IS, size, pErr);
|
||||
nsMemory::Free(pwc);
|
||||
return success;
|
||||
}
|
||||
case nsIDataType::VTYPE_INTERFACE:
|
||||
case nsIDataType::VTYPE_INTERFACE_IS:
|
||||
{
|
||||
nsISupports *pi;
|
||||
nsID* piid;
|
||||
if (NS_FAILED(variant->GetAsInterface(&piid, &xpctvar.val.p)))
|
||||
if (NS_FAILED(variant->GetAsInterface(&piid, (void **)&pi)))
|
||||
return false;
|
||||
|
||||
iid = *piid;
|
||||
nsMemory::Free((char*)piid);
|
||||
|
||||
xpctvar.type = (uint8_t)TD_INTERFACE_IS_TYPE;
|
||||
if (xpctvar.val.p)
|
||||
xpctvar.SetValNeedsCleanup();
|
||||
break;
|
||||
bool success = XPCConvert::NativeData2JS(lccx, pJSVal, (const void*)&pi,
|
||||
TD_INTERFACE_IS_TYPE, &iid, pErr);
|
||||
if (pi)
|
||||
pi->Release();
|
||||
return success;
|
||||
}
|
||||
case nsIDataType::VTYPE_ARRAY:
|
||||
{
|
||||
|
@ -550,7 +577,7 @@ XPCVariant::VariantDataToJS(XPCLazyCallContext& lccx,
|
|||
|
||||
// must exit via VARIANT_DONE from here on...
|
||||
du.mType = nsIDataType::VTYPE_ARRAY;
|
||||
success = false;
|
||||
bool success = false;
|
||||
|
||||
nsXPTType conversionType;
|
||||
uint16_t elementType = du.u.array.mArrayType;
|
||||
|
@ -633,32 +660,6 @@ VARIANT_DONE:
|
|||
NS_ERROR("bad type in variant!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we are here then we need to convert the data in the xpctvar.
|
||||
|
||||
if (xpctvar.type.TagPart() == TD_PSTRING_SIZE_IS ||
|
||||
xpctvar.type.TagPart() == TD_PWSTRING_SIZE_IS) {
|
||||
success = XPCConvert::NativeStringWithSize2JS(cx, pJSVal,
|
||||
(const void*)&xpctvar.val,
|
||||
xpctvar.type,
|
||||
size, pErr);
|
||||
} else {
|
||||
success = XPCConvert::NativeData2JS(lccx, pJSVal,
|
||||
(const void*)&xpctvar.val,
|
||||
xpctvar.type,
|
||||
&iid, pErr);
|
||||
}
|
||||
|
||||
// We may have done something in the above code that requires cleanup.
|
||||
if (xpctvar.DoesValNeedCleanup()) {
|
||||
if (type == nsIDataType::VTYPE_INTERFACE ||
|
||||
type == nsIDataType::VTYPE_INTERFACE_IS)
|
||||
((nsISupports*)xpctvar.val.p)->Release();
|
||||
else
|
||||
nsMemory::Free((char*)xpctvar.val.p);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
|
|
@ -2058,7 +2058,7 @@ XPCWrappedNative::GetSameCompartmentSecurityWrapper(JSContext *cx)
|
|||
{
|
||||
// Grab the current state of affairs.
|
||||
RootedObject flat(cx, GetFlatJSObject());
|
||||
JSObject *wrapper = GetWrapper();
|
||||
RootedObject wrapper(cx, GetWrapper());
|
||||
|
||||
// If we already have a wrapper, it must be what we want.
|
||||
if (wrapper)
|
||||
|
|
|
@ -2031,7 +2031,7 @@ xpc_ActivateDebugMode()
|
|||
JSContext*
|
||||
nsXPConnect::GetCurrentJSContext()
|
||||
{
|
||||
JSContext *cx = XPCJSRuntime::Get()->GetJSContextStack()->Peek();
|
||||
JSContext *cx = GetRuntime()->GetJSContextStack()->Peek();
|
||||
return xpc_UnmarkGrayContext(cx);
|
||||
}
|
||||
|
||||
|
@ -2039,7 +2039,7 @@ nsXPConnect::GetCurrentJSContext()
|
|||
JSContext*
|
||||
nsXPConnect::GetSafeJSContext()
|
||||
{
|
||||
return XPCJSRuntime::Get()->GetJSContextStack()->GetSafeJSContext();
|
||||
return GetRuntime()->GetJSContextStack()->GetSafeJSContext();
|
||||
}
|
||||
|
||||
namespace xpc {
|
||||
|
@ -2373,14 +2373,14 @@ nsXPConnect::SetDebugModeWhenPossible(bool mode, bool allowSyncDisable)
|
|||
NS_IMETHODIMP
|
||||
nsXPConnect::GetTelemetryValue(JSContext *cx, jsval *rval)
|
||||
{
|
||||
JSObject *obj = JS_NewObject(cx, NULL, NULL, NULL);
|
||||
RootedObject obj(cx, JS_NewObject(cx, NULL, NULL, NULL));
|
||||
if (!obj)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
unsigned attrs = JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT;
|
||||
|
||||
size_t i = JS_SetProtoCalled(cx);
|
||||
jsval v = DOUBLE_TO_JSVAL(i);
|
||||
RootedValue v(cx, DOUBLE_TO_JSVAL(i));
|
||||
if (!JS_DefineProperty(cx, obj, "setProto", v, NULL, NULL, attrs))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
|
|
@ -283,7 +283,7 @@ WrapperFactory::PrepareForWrapping(JSContext *cx, HandleObject scope,
|
|||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
DEBUG_CheckUnwrapSafety(JSObject *obj, js::Wrapper *handler,
|
||||
DEBUG_CheckUnwrapSafety(HandleObject obj, js::Wrapper *handler,
|
||||
JSCompartment *origin, JSCompartment *target)
|
||||
{
|
||||
if (AccessCheck::isChrome(target) || xpc::IsUniversalXPConnectEnabled(target)) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче