Bug 1149358: Ensure that plugin streams are not manipulated by PluginAsyncSurrogate if plugin destruction is imminent; r=jimm

--HG--
extra : rebase_source : 440ecf2bd74fd5e28ed715e7e477d9fd55d18697
This commit is contained in:
Aaron Klotz 2015-04-01 16:53:47 -06:00
Родитель 43939414b8
Коммит 161897ae0e
2 изменённых файлов: 31 добавлений и 20 удалений

Просмотреть файл

@ -436,16 +436,20 @@ PluginAsyncSurrogate::SetStreamType(NPStream* aStream, uint16_t aStreamType)
void
PluginAsyncSurrogate::OnInstanceCreated(PluginInstanceParent* aInstance)
{
for (uint32_t i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) {
PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i];
uint16_t streamType = NP_NORMAL;
NPError curError = aInstance->NPP_NewStream(
const_cast<char*>(NullableStringGet(curPendingCall.mType)),
curPendingCall.mStream, curPendingCall.mSeekable,
&streamType);
if (curError != NPERR_NO_ERROR) {
// If we failed here then the send failed and we need to clean up
DestroyAsyncStream(curPendingCall.mStream);
if (!mDestroyPending) {
// If NPP_Destroy has already been called then these streams have already
// been cleaned up on the browser side and are no longer valid.
for (uint32_t i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) {
PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i];
uint16_t streamType = NP_NORMAL;
NPError curError = aInstance->NPP_NewStream(
const_cast<char*>(NullableStringGet(curPendingCall.mType)),
curPendingCall.mStream, curPendingCall.mSeekable,
&streamType);
if (curError != NPERR_NO_ERROR) {
// If we failed here then the send failed and we need to clean up
DestroyAsyncStream(curPendingCall.mStream);
}
}
}
mPendingNewStreamCalls.Clear();
@ -543,10 +547,12 @@ PluginAsyncSurrogate::AsyncCallArriving()
void
PluginAsyncSurrogate::NotifyAsyncInitFailed()
{
// Clean up any pending NewStream requests
for (uint32_t i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) {
PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i];
DestroyAsyncStream(curPendingCall.mStream);
if (!mDestroyPending) {
// Clean up any pending NewStream requests
for (uint32_t i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) {
PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i];
DestroyAsyncStream(curPendingCall.mStream);
}
}
mPendingNewStreamCalls.Clear();
@ -556,9 +562,7 @@ PluginAsyncSurrogate::NotifyAsyncInitFailed()
return;
}
nsPluginInstanceOwner* owner = inst->GetOwner();
if (!owner) {
return;
}
MOZ_ASSERT(owner);
owner->NotifyHostAsyncInitFailed();
}

Просмотреть файл

@ -1739,10 +1739,17 @@ PluginInstanceParent::RecvAsyncNPP_NewResult(const NPError& aResult)
mSurrogate->SetAcceptingCalls(true);
}
// It is possible for a plugin instance to outlive its owner (eg. When a
// PluginDestructionGuard was on the stack at the time the owner was being
// destroyed). We need to handle that case.
nsPluginInstanceOwner* owner = GetOwner();
// It is possible for a plugin instance to outlive its owner when async
// plugin init is turned on, so we need to handle that case.
if (aResult != NPERR_NO_ERROR || !owner) {
if (!owner) {
// We can't do anything at this point, just return. Any pending browser
// streams will be cleaned up when the plugin instance is destroyed.
return true;
}
if (aResult != NPERR_NO_ERROR) {
mSurrogate->NotifyAsyncInitFailed();
return true;
}