From 74d79c82a7717ab6742762f833b63f53e85ce1a1 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Tue, 25 Apr 2017 14:07:31 +0200 Subject: [PATCH] Bug 1359172 - RemoteInputStream must create a correct inputStream when used and sliced in a separate process, r=smaug --- dom/file/ipc/Blob.cpp | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/dom/file/ipc/Blob.cpp b/dom/file/ipc/Blob.cpp index ee70bad132a6..4c9821af58c0 100644 --- a/dom/file/ipc/Blob.cpp +++ b/dom/file/ipc/Blob.cpp @@ -50,6 +50,7 @@ #include "nsStringStream.h" #include "nsThreadUtils.h" #include "nsXULAppAPI.h" +#include "SlicedInputStream.h" #include "StreamBlobImpl.h" #include "WorkerPrivate.h" #include "WorkerRunnable.h" @@ -2765,19 +2766,44 @@ CreateStreamHelper::GetStream(nsIInputStream** aInputStream) MOZ_ASSERT(baseRemoteBlobImpl); if (EventTargetIsOnCurrentThread(baseRemoteBlobImpl->GetActorEventTarget())) { + // RunInternal will populate mInputStream using the correct mStart/mLength + // value. RunInternal(baseRemoteBlobImpl, false); } else if (PBackgroundChild* manager = mozilla::ipc::BackgroundChild::GetForCurrentThread()) { + // In case we are on a PBackground thread and this is not the owning thread, + // we need to create a new actor here. This actor must be created for the + // baseRemoteBlobImpl, which can be the mRemoteBlobImpl or the parent one, + // in case we are dealing with a sliced blob. BlobChild* blobChild = BlobChild::GetOrCreate(manager, baseRemoteBlobImpl); MOZ_ASSERT(blobChild); - RefPtr blobImpl = blobChild->GetBlobImpl(); - MOZ_ASSERT(blobImpl); + // Note that baseBlobImpl is generated by the actor, and the actor is + // created from the baseRemoteBlobImpl. This means that baseBlobImpl is the + // remote blobImpl on PBackground of baseRemoteBlobImpl. + RefPtr baseBlobImpl = blobChild->GetBlobImpl(); + MOZ_ASSERT(baseBlobImpl); ErrorResult rv; - blobImpl->GetInternalStream(aInputStream, rv); + nsCOMPtr baseInputStream; + baseBlobImpl->GetInternalStream(getter_AddRefs(baseInputStream), rv); + if (NS_WARN_IF(rv.Failed())) { + return rv.StealNSResult(); + } + + // baseInputStream is the stream of the baseRemoteBlobImpl. If + // mRemoteBlobImpl is a slice of baseRemoteBlobImpl, here we need to slice + // baseInputStream. + if (mRemoteBlobImpl->IsSlice()) { + RefPtr slicedInputStream = + new SlicedInputStream(baseInputStream, mStart, mLength); + slicedInputStream.forget(aInputStream); + } else { + baseInputStream.forget(aInputStream); + } + mRemoteBlobImpl = nullptr; mDone = true; - return rv.StealNSResult(); + return NS_OK; } else { nsresult rv = baseRemoteBlobImpl->DispatchToTarget(this); if (NS_WARN_IF(NS_FAILED(rv))) {