Bug 1288997 - AutoIPCStream DTOR must run after the use of the inputStream for PBlob, r=jld a=gchang
--- a/dom/base/nsHostObjectProtocolHandler.cpp
+++ b/dom/base/nsHostObjectProtocolHandler.cpp
@@ -134,21 +134,16 @@ BroadcastBlobURLRegistration(const nsACS
MOZ_ASSERT(aBlobImpl);
if (XRE_IsParentProcess()) {
ContentParent::BroadcastBlobURLRegistration(aURI, aBlobImpl,
aPrincipal);
return;
}
- // We don't need to broadcast Blob URL if we have just 1 content process.
- if (Preferences::GetInt("dom.ipc.processCount", 0) <= 1) {
- return;
- }
-
ContentChild* cc = ContentChild::GetSingleton();
BlobChild* actor = cc->GetOrCreateActorForBlobImpl(aBlobImpl);
if (NS_WARN_IF(!actor)) {
return;
}
Unused << NS_WARN_IF(!cc->SendStoreAndBroadcastBlobURLRegistration(
nsCString(aURI), actor, IPC::Principal(aPrincipal)));
--- a/dom/ipc/Blob.cpp
+++ b/dom/ipc/Blob.cpp
@@ -910,17 +910,18 @@ CreateBlobImpl(const ParentBlobConstruct
RefPtr<BlobImpl> blobImpl =
CreateBlobImplFromBlobData(aBlobData, metadata);
return blobImpl.forget();
}
template <class ChildManagerType>
void
BlobDataFromBlobImpl(ChildManagerType* aManager, BlobImpl* aBlobImpl,
- BlobData& aBlobData)
+ BlobData& aBlobData,
+ nsTArray<UniquePtr<AutoIPCStream>>& aIPCStreams)
{
MOZ_ASSERT(gProcessType != GeckoProcessType_Default);
MOZ_ASSERT(aBlobImpl);
const nsTArray<RefPtr<BlobImpl>>* subBlobs = aBlobImpl->GetSubBlobImpls();
if (subBlobs) {
MOZ_ASSERT(subBlobs->Length());
@@ -929,17 +930,17 @@ BlobDataFromBlobImpl(ChildManagerType* a
nsTArray<BlobData>& subBlobDatas = aBlobData.get_ArrayOfBlobData();
subBlobDatas.SetLength(subBlobs->Length());
for (uint32_t count = subBlobs->Length(), index = 0;
index < count;
index++) {
BlobDataFromBlobImpl(aManager, subBlobs->ElementAt(index),
- subBlobDatas[index]);
+ subBlobDatas[index], aIPCStreams);
}
return;
}
nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlobImpl);
if (remoteBlob) {
BlobChild* actor = remoteBlob->GetBlobChild();
@@ -949,19 +950,21 @@ BlobDataFromBlobImpl(ChildManagerType* a
return;
}
ErrorResult rv;
nsCOMPtr<nsIInputStream> inputStream;
aBlobImpl->GetInternalStream(getter_AddRefs(inputStream), rv);
MOZ_ALWAYS_TRUE(!rv.Failed());
- AutoIPCStream autoStream;
- autoStream.Serialize(inputStream, aManager);
- aBlobData = autoStream.TakeValue();
+ UniquePtr<AutoIPCStream> autoStream(new AutoIPCStream());
+ autoStream->Serialize(inputStream, aManager);
+ aBlobData = autoStream->TakeValue();
+
+ aIPCStreams.AppendElement(Move(autoStream));
}
RemoteInputStream::RemoteInputStream(BlobImpl* aBlobImpl,
uint64_t aStart,
uint64_t aLength)
: mMonitor("RemoteInputStream.mMonitor")
, mActor(nullptr)
, mBlobImpl(aBlobImpl)
@@ -3339,28 +3342,29 @@ BlobChild::GetOrCreateFromImpl(ChildMana
if (NS_WARN_IF(NS_FAILED(aBlobImpl->SetMutable(false)))) {
return nullptr;
}
MOZ_ASSERT(!aBlobImpl->IsSizeUnknown());
MOZ_ASSERT(!aBlobImpl->IsDateUnknown());
AnyBlobConstructorParams blobParams;
+ nsTArray<UniquePtr<AutoIPCStream>> autoIPCStreams;
if (gProcessType == GeckoProcessType_Default) {
RefPtr<BlobImpl> sameProcessImpl = aBlobImpl;
auto addRefedBlobImpl =
reinterpret_cast<intptr_t>(sameProcessImpl.forget().take());
blobParams = SameProcessBlobConstructorParams(addRefedBlobImpl);
} else {
// BlobData is going to be populate here and it _must_ be send via IPC in
// order to avoid leaks.
BlobData blobData;
- BlobDataFromBlobImpl(aManager, aBlobImpl, blobData);
+ BlobDataFromBlobImpl(aManager, aBlobImpl, blobData, autoIPCStreams);
nsString contentType;
aBlobImpl->GetType(contentType);
ErrorResult rv;
uint64_t length = aBlobImpl->GetSize(rv);
MOZ_ASSERT(!rv.Failed());
@@ -3385,16 +3389,17 @@ BlobChild::GetOrCreateFromImpl(ChildMana
BlobChild* actor = new BlobChild(aManager, aBlobImpl);
ParentBlobConstructorParams params(blobParams);
if (NS_WARN_IF(!aManager->SendPBlobConstructor(actor, params))) {
return nullptr;
}
+ autoIPCStreams.Clear();
return actor;
}
// static
template <class ChildManagerType>
BlobChild*
BlobChild::CreateFromParams(ChildManagerType* aManager,
const ChildBlobConstructorParams& aParams)