Bug 873735 part 1. Fix the more or less mechanical browser rooting hazards. r=terrence

This commit is contained in:
Boris Zbarsky 2013-05-20 08:40:06 -04:00
parent 7e57098b48
commit be0882e3a1
21 changed files with 64 additions and 48 deletions

View File

@ -383,10 +383,11 @@ private:
// Returns null if a principal cannot be found; generally callers
// should error out at that point.
static nsIPrincipal* doGetObjectPrincipal(JSObject *obj);
static nsIPrincipal* doGetObjectPrincipal(JS::Handle<JSObject*> obj);
#ifdef DEBUG
static nsIPrincipal*
old_doGetObjectPrincipal(JSObject *obj, bool aAllowShortCircuit = true);
old_doGetObjectPrincipal(JS::Handle<JSObject*> obj,
bool aAllowShortCircuit = true);
#endif
// Returns null if a principal cannot be found. Note that rv can be NS_OK

View File

@ -1633,7 +1633,7 @@ nsScriptSecurityManager::CheckFunctionAccess(JSContext *aCx, void *aFunObj,
/*
** Get origin of subject and object and compare.
*/
JSObject* obj = (JSObject*)aTargetObj;
JS::Rooted<JSObject*> obj(aCx, (JSObject*)aTargetObj);
nsIPrincipal* object = doGetObjectPrincipal(obj);
if (!object)
@ -2023,7 +2023,8 @@ NS_IMETHODIMP
nsScriptSecurityManager::GetObjectPrincipal(JSContext *aCx, JSObject *aObj,
nsIPrincipal **result)
{
*result = doGetObjectPrincipal(aObj);
JS::Rooted<JSObject*> obj(aCx, aObj);
*result = doGetObjectPrincipal(obj);
if (!*result)
return NS_ERROR_FAILURE;
NS_ADDREF(*result);
@ -2032,7 +2033,7 @@ nsScriptSecurityManager::GetObjectPrincipal(JSContext *aCx, JSObject *aObj,
// static
nsIPrincipal*
nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj)
nsScriptSecurityManager::doGetObjectPrincipal(JS::Handle<JSObject*> aObj)
{
JSCompartment *compartment = js::GetObjectCompartment(aObj);
JSPrincipals *principals = JS_GetCompartmentPrincipals(compartment);
@ -2052,14 +2053,15 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj)
#ifdef DEBUG
// static
nsIPrincipal*
nsScriptSecurityManager::old_doGetObjectPrincipal(JSObject *aObj,
nsScriptSecurityManager::old_doGetObjectPrincipal(JS::Handle<JSObject*> aObj,
bool aAllowShortCircuit)
{
NS_ASSERTION(aObj, "Bad call to doGetObjectPrincipal()!");
nsIPrincipal* result = nullptr;
JS::RootedObject obj(sXPConnect->GetCurrentJSContext(), aObj);
JSObject* origObj = obj;
JSContext* cx = sXPConnect->GetCurrentJSContext();
JS::RootedObject obj(cx, aObj);
JS::RootedObject origObj(cx, obj);
js::Class *jsClass = js::GetObjectClass(obj);
// A common case seen in this code is that we enter this function

View File

@ -2204,7 +2204,7 @@ public:
nsRefPtr<nsFrameMessageManager> mm = tabChild->GetInnerManager();
mm->ReceiveMessage(static_cast<EventTarget*>(tabChild), mMessage,
false, &data, nullptr, nullptr, nullptr);
false, &data, JS::NullPtr(), nullptr, nullptr);
}
return NS_OK;
}

View File

@ -626,7 +626,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
const nsAString& aMessage,
bool aSync,
const StructuredCloneData* aCloneData,
JSObject* aObjectsArray,
JS::Handle<JSObject*> aObjectsArray,
InfallibleTArray<nsString>* aJSONRetVal,
JSContext* aContext)
{
@ -1206,7 +1206,7 @@ public:
nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sChildProcessManager;
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), mMessage,
false, &data, nullptr, nullptr, nullptr);
false, &data, JS::NullPtr(), nullptr, nullptr);
}
return NS_OK;
}
@ -1336,7 +1336,7 @@ public:
nsRefPtr<nsFrameMessageManager> ppm =
nsFrameMessageManager::sSameProcessParentManager;
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
mMessage, false, &data, nullptr, nullptr, nullptr);
mMessage, false, &data, JS::NullPtr(), nullptr, nullptr);
}
return NS_OK;
}
@ -1376,7 +1376,7 @@ public:
if (nsFrameMessageManager::sSameProcessParentManager) {
nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sSameProcessParentManager;
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), aMessage,
true, &aData, nullptr, aJSONRetVal);
true, &aData, JS::NullPtr(), aJSONRetVal);
}
return true;
}

View File

@ -182,7 +182,7 @@ public:
nsresult ReceiveMessage(nsISupports* aTarget, const nsAString& aMessage,
bool aSync, const StructuredCloneData* aCloneData,
JSObject* aObjectsArray,
JS::Handle<JSObject*> aObjectsArray,
InfallibleTArray<nsString>* aJSONRetVal,
JSContext* aContext = nullptr);

View File

@ -38,7 +38,8 @@ nsInProcessTabChildGlobal::DoSendSyncMessage(const nsAString& aMessage,
}
if (mChromeMessageManager) {
nsRefPtr<nsFrameMessageManager> mm = mChromeMessageManager;
mm->ReceiveMessage(mOwner, aMessage, true, &aData, nullptr, aJSONRetVal);
mm->ReceiveMessage(mOwner, aMessage, true, &aData, JS::NullPtr(),
aJSONRetVal);
}
return true;
}
@ -73,7 +74,7 @@ public:
nsRefPtr<nsFrameMessageManager> mm = mTabChild->mChromeMessageManager;
mm->ReceiveMessage(mTabChild->mOwner, mMessage, false, &data,
nullptr, nullptr, nullptr);
JS::NullPtr(), nullptr, nullptr);
}
return NS_OK;
}

View File

@ -264,7 +264,8 @@ nsXBLProtoImplMethod::Write(nsIScriptContext* aContext,
rv = aStream->WriteWStringZ(mName);
NS_ENSURE_SUCCESS(rv, rv);
return XBL_SerializeFunction(aContext, aStream, mJSMethodObject);
return XBL_SerializeFunction(aContext, aStream,
JS::Handle<JSObject*>::fromMarkedLocation(&mJSMethodObject));
}
return NS_OK;
@ -369,7 +370,8 @@ nsXBLProtoImplAnonymousMethod::Write(nsIScriptContext* aContext,
nsresult rv = aStream->Write8(aType);
NS_ENSURE_SUCCESS(rv, rv);
rv = XBL_SerializeFunction(aContext, aStream, mJSMethodObject);
rv = XBL_SerializeFunction(aContext, aStream,
JS::Handle<JSObject*>::fromMarkedLocation(&mJSMethodObject));
NS_ENSURE_SUCCESS(rv, rv);
}

View File

@ -373,12 +373,14 @@ nsXBLProtoImplProperty::Write(nsIScriptContext* aContext,
NS_ENSURE_SUCCESS(rv, rv);
if (mJSAttributes & JSPROP_GETTER) {
rv = XBL_SerializeFunction(aContext, aStream, mJSGetterObject);
rv = XBL_SerializeFunction(aContext, aStream,
JS::Handle<JSObject*>::fromMarkedLocation(&mJSGetterObject));
NS_ENSURE_SUCCESS(rv, rv);
}
if (mJSAttributes & JSPROP_SETTER) {
rv = XBL_SerializeFunction(aContext, aStream, mJSSetterObject);
rv = XBL_SerializeFunction(aContext, aStream,
JS::Handle<JSObject*>::fromMarkedLocation(&mJSSetterObject));
NS_ENSURE_SUCCESS(rv, rv);
}

View File

@ -13,11 +13,10 @@ using namespace mozilla;
nsresult
XBL_SerializeFunction(nsIScriptContext* aContext,
nsIObjectOutputStream* aStream,
JSObject* aFunctionObject)
JS::Handle<JSObject*> aFunction)
{
AutoPushJSContext cx(aContext->GetNativeContext());
JS::RootedObject function(cx, aFunctionObject);
return nsContentUtils::XPConnect()->WriteFunction(aStream, cx, function);
return nsContentUtils::XPConnect()->WriteFunction(aStream, cx, aFunction);
}
nsresult

View File

@ -79,7 +79,7 @@ PR_STATIC_ASSERT(XBLBinding_Serialize_CustomNamespace >= kNameSpaceID_LastBuilti
nsresult
XBL_SerializeFunction(nsIScriptContext* aContext,
nsIObjectOutputStream* aStream,
JSObject* aFunctionObject);
JS::Handle<JSObject*> aFunctionObject);
nsresult
XBL_DeserializeFunction(nsIScriptContext* aContext,

View File

@ -2526,7 +2526,7 @@ nsXULPrototypeScript::DeserializeOutOfLine(nsIObjectInputStream* aInput,
bool isChrome = false;
mSrcURI->SchemeIs("chrome", &isChrome);
if (isChrome)
cache->PutScript(mSrcURI, mScriptObject);
cache->PutScript(mSrcURI, GetScriptObject());
}
cache->FinishInputStream(mSrcURI);
} else {
@ -2628,9 +2628,9 @@ nsXULPrototypeScript::Set(JSScript* aObject)
return;
}
mScriptObject = aObject;
nsContentUtils::HoldJSObjects(
this, NS_CYCLE_COLLECTION_PARTICIPANT(nsXULPrototypeNode));
mScriptObject = aObject;
}
//----------------------------------------------------------------------

View File

@ -236,9 +236,13 @@ public:
void Set(JSScript* aObject);
JSScript *GetScriptObject()
// It's safe to return a handle because we trace mScriptObject, no one ever
// uses the handle (or the script object) past the point at which the
// nsXULPrototypeScript dies, and we can't get memmoved so the
// &mScriptObject pointer can't go stale.
JS::Handle<JSScript*> GetScriptObject()
{
return mScriptObject;
return JS::Handle<JSScript*>::fromMarkedLocation(&mScriptObject);
}
void TraceScriptObject(JSTracer* aTrc)

View File

@ -3644,7 +3644,8 @@ XULDocument::OnStreamComplete(nsIStreamLoader* aLoader,
nsresult
XULDocument::ExecuteScript(nsIScriptContext * aContext, JSScript* aScriptObject)
XULDocument::ExecuteScript(nsIScriptContext * aContext,
JS::Handle<JSScript*> aScriptObject)
{
NS_PRECONDITION(aScriptObject != nullptr && aContext != nullptr, "null ptr");
if (! aScriptObject || ! aContext)
@ -3653,9 +3654,8 @@ XULDocument::ExecuteScript(nsIScriptContext * aContext, JSScript* aScriptObject)
NS_ENSURE_TRUE(mScriptGlobalObject, NS_ERROR_NOT_INITIALIZED);
// Execute the precompiled script with the given version
JS::Rooted<JSScript*> script(aContext->GetNativeContext(), aScriptObject);
JSObject* global = mScriptGlobalObject->GetGlobalJSObject();
return aContext->ExecuteScript(script, global);
return aContext->ExecuteScript(aScriptObject, global);
}
nsresult

View File

@ -403,7 +403,8 @@ protected:
* Execute the precompiled script object scoped by this XUL document's
* containing window object, and using its associated script context.
*/
nsresult ExecuteScript(nsIScriptContext *aContext, JSScript* aScriptObject);
nsresult ExecuteScript(nsIScriptContext *aContext,
JS::Handle<JSScript*> aScriptObject);
/**
* Helper method for the above that uses aScript to find the appropriate

View File

@ -205,7 +205,8 @@ nsXULPrototypeCache::GetScript(nsIURI* aURI)
}
nsresult
nsXULPrototypeCache::PutScript(nsIURI* aURI, JSScript* aScriptObject)
nsXULPrototypeCache::PutScript(nsIURI* aURI,
JS::Handle<JSScript*> aScriptObject)
{
CacheScriptEntry existingEntry;
if (mScriptTable.Get(aURI, &existingEntry)) {

View File

@ -69,7 +69,7 @@ public:
nsresult PutPrototype(nsXULPrototypeDocument* aDocument);
JSScript* GetScript(nsIURI* aURI);
nsresult PutScript(nsIURI* aURI, JSScript* aScriptObject);
nsresult PutScript(nsIURI* aURI, JS::Handle<JSScript*> aScriptObject);
nsXBLDocumentInfo* GetXBLDocumentInfo(nsIURI* aURL) {
return mXBLDocTable.GetWeak(aURL);

View File

@ -1026,7 +1026,7 @@ ContentChild::RecvAsyncMessage(const nsString& aMsg,
if (cpm) {
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForChild(aData);
cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()),
aMsg, false, &cloneData, nullptr, nullptr);
aMsg, false, &cloneData, JS::NullPtr(), nullptr);
}
return true;
}

View File

@ -866,7 +866,7 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
if (ppm) {
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
CHILD_PROCESS_SHUTDOWN_MESSAGE, false,
nullptr, nullptr, nullptr);
nullptr, JS::NullPtr(), nullptr);
}
nsCOMPtr<nsIThreadObserver>
kungFuDeathGrip(static_cast<nsIThreadObserver*>(this));
@ -2331,7 +2331,7 @@ ContentParent::RecvSyncMessage(const nsString& aMsg,
if (ppm) {
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
aMsg, true, &cloneData, nullptr, aRetvals);
aMsg, true, &cloneData, JS::NullPtr(), aRetvals);
}
return true;
}
@ -2344,7 +2344,7 @@ ContentParent::RecvAsyncMessage(const nsString& aMsg,
if (ppm) {
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
aMsg, false, &cloneData, nullptr, nullptr);
aMsg, false, &cloneData, JS::NullPtr(), nullptr);
}
return true;
}

View File

@ -1436,7 +1436,7 @@ TabChild::DispatchMessageManagerMessage(const nsAString& aMessageName,
nsRefPtr<nsFrameMessageManager> mm =
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal),
aMessageName, false, &cloneData, nullptr, nullptr);
aMessageName, false, &cloneData, JS::NullPtr(), nullptr);
}
static void
@ -1974,7 +1974,7 @@ TabChild::RecvAsyncMessage(const nsString& aMessage,
nsRefPtr<nsFrameMessageManager> mm =
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal),
aMessage, false, &cloneData, nullptr, nullptr);
aMessage, false, &cloneData, JS::NullPtr(), nullptr);
}
return true;
}

View File

@ -1102,7 +1102,7 @@ TabParent::ReceiveMessage(const nsString& aMessage,
uint32_t len = 0; //TODO: obtain a real value in bug 572685
// Because we want JS messages to have always the same properties,
// create array even if len == 0.
JSObject* objectsArray = JS_NewArrayObject(ctx, len, NULL);
JS::Rooted<JSObject*> objectsArray(ctx, JS_NewArrayObject(ctx, len, NULL));
if (!objectsArray) {
return false;
}

View File

@ -13,7 +13,8 @@ nsTArrayToJSArray(JSContext* aCx, const nsTArray<T>& aSourceArray,
MOZ_ASSERT(aCx);
JSAutoRequest ar(aCx);
JSObject* arrayObj = JS_NewArrayObject(aCx, aSourceArray.Length(), nullptr);
JS::Rooted<JSObject*> arrayObj(aCx,
JS_NewArrayObject(aCx, aSourceArray.Length(), nullptr));
if (!arrayObj) {
NS_WARNING("JS_NewArrayObject failed!");
return NS_ERROR_OUT_OF_MEMORY;
@ -27,11 +28,12 @@ nsTArrayToJSArray(JSContext* aCx, const nsTArray<T>& aSourceArray,
nsresult rv = aSourceArray[index]->QueryInterface(NS_GET_IID(nsISupports), getter_AddRefs(obj));
NS_ENSURE_SUCCESS(rv, rv);
jsval wrappedVal;
rv = nsContentUtils::WrapNative(aCx, global, obj, &wrappedVal, nullptr, true);
JS::Rooted<JS::Value> wrappedVal(aCx);
rv = nsContentUtils::WrapNative(aCx, global, obj, wrappedVal.address(),
nullptr, true);
NS_ENSURE_SUCCESS(rv, rv);
if (!JS_SetElement(aCx, arrayObj, index, &wrappedVal)) {
if (!JS_SetElement(aCx, arrayObj, index, wrappedVal.address())) {
NS_WARNING("JS_SetElement failed!");
return NS_ERROR_FAILURE;
}
@ -55,7 +57,8 @@ nsTArrayToJSArray<nsString>(JSContext* aCx,
MOZ_ASSERT(aCx);
JSAutoRequest ar(aCx);
JSObject* arrayObj = JS_NewArrayObject(aCx, aSourceArray.Length(), nullptr);
JS::Rooted<JSObject*> arrayObj(aCx,
JS_NewArrayObject(aCx, aSourceArray.Length(), nullptr));
if (!arrayObj) {
NS_WARNING("JS_NewArrayObject failed!");
return NS_ERROR_OUT_OF_MEMORY;
@ -70,9 +73,9 @@ nsTArrayToJSArray<nsString>(JSContext* aCx,
return NS_ERROR_OUT_OF_MEMORY;
}
jsval wrappedVal = STRING_TO_JSVAL(s);
JS::Rooted<JS::Value> wrappedVal(aCx, STRING_TO_JSVAL(s));
if (!JS_SetElement(aCx, arrayObj, index, &wrappedVal)) {
if (!JS_SetElement(aCx, arrayObj, index, wrappedVal.address())) {
NS_WARNING("JS_SetElement failed!");
return NS_ERROR_FAILURE;
}