Bug 910010 - Implementation of PFileDescriptorSet - part 1, r=khuey

This commit is contained in:
Andrea Marchesini 2014-03-25 18:37:13 +00:00
parent 833cf6fbbf
commit 623c6e2389
28 changed files with 421 additions and 125 deletions

View File

@ -376,8 +376,11 @@ NS_IMETHODIMP nsDefaultURIFixup::KeywordToURI(const nsACString& aKeyword,
}
if (aPostData) {
nsCOMPtr<nsIInputStream> temp = DeserializeInputStream(postData);
nsTArray<ipc::FileDescriptor> fds;
nsCOMPtr<nsIInputStream> temp = DeserializeInputStream(postData, fds);
temp.forget(aPostData);
MOZ_ASSERT(fds.IsEmpty());
}
nsCOMPtr<nsIURI> temp = DeserializeURI(uri);

View File

@ -21,6 +21,7 @@
#include "mozilla/Monitor.h"
#include "mozilla/unused.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "mozilla/dom/PFileDescriptorSetParent.h"
#include "nsDOMFile.h"
#include "nsProxyRelease.h"
#include "nsThreadUtils.h"
@ -29,6 +30,7 @@
#include "ContentChild.h"
#include "ContentParent.h"
#include "nsNetCID.h"
#include "FileDescriptorSetChild.h"
#define PRIVATE_REMOTE_INPUT_STREAM_IID \
{0x30c7699f, 0x51d2, 0x48c8, {0xad, 0x56, 0xc0, 0x16, 0xd7, 0x6f, 0x71, 0x27}}
@ -167,7 +169,8 @@ public:
}
void
Serialize(InputStreamParams& aParams)
Serialize(InputStreamParams& aParams,
FileDescriptorArray& /* aFileDescriptors */)
{
nsCOMPtr<nsIRemoteBlob> remote = do_QueryInterface(mSourceBlob);
MOZ_ASSERT(remote);
@ -182,7 +185,8 @@ public:
}
bool
Deserialize(const InputStreamParams& aParams)
Deserialize(const InputStreamParams& aParams,
const FileDescriptorArray& /* aFileDescriptors */)
{
// See InputStreamUtils.cpp to see how deserialization of a
// RemoteInputStream is special-cased.
@ -448,21 +452,64 @@ public:
private:
// This method is only called by the IPDL message machinery.
virtual bool
Recv__delete__(const InputStreamParams& aParams) MOZ_OVERRIDE
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mRemoteStream);
nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(aParams);
if (!stream) {
return false;
}
mRemoteStream->SetStream(stream);
return true;
}
Recv__delete__(const InputStreamParams& aParams,
const OptionalFileDescriptorSet& aFDs) MOZ_OVERRIDE;
};
template <>
bool
InputStreamActor<Parent>::Recv__delete__(const InputStreamParams& aParams,
const OptionalFileDescriptorSet& aFDs)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mRemoteStream);
if (aFDs.type() != OptionalFileDescriptorSet::Tvoid_t) {
NS_WARNING("Child cannot send FileDescriptors to the parent!");
return false;
}
nsTArray<FileDescriptor> fds;
nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(aParams, fds);
if (!stream) {
return false;
}
MOZ_ASSERT(fds.IsEmpty());
mRemoteStream->SetStream(stream);
return true;
}
template <>
bool
InputStreamActor<Child>::Recv__delete__(const InputStreamParams& aParams,
const OptionalFileDescriptorSet& aFDs)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mRemoteStream);
nsTArray<FileDescriptor> fds;
if (aFDs.type() == OptionalFileDescriptorSet::TPFileDescriptorSetChild) {
FileDescriptorSetChild* fdSetActor =
static_cast<FileDescriptorSetChild*>(aFDs.get_PFileDescriptorSetChild());
MOZ_ASSERT(fdSetActor);
fdSetActor->ForgetFileDescriptors(fds);
MOZ_ASSERT(!fds.IsEmpty());
fdSetActor->Send__delete__(fdSetActor);
}
nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(aParams, fds);
if (!stream) {
return false;
}
mRemoteStream->SetStream(stream);
return true;
}
template <ActorFlavorEnum ActorFlavor>
inline
already_AddRefed<nsIDOMBlob>
@ -678,11 +725,34 @@ private:
MOZ_ASSERT(mStreamActor);
InputStreamParams params;
serializable->Serialize(params);
nsAutoTArray<FileDescriptor, 10> fds;
serializable->Serialize(params, fds);
MOZ_ASSERT(params.type() != InputStreamParams::T__None);
unused << mStreamActor->Send__delete__(mStreamActor, params);
PFileDescriptorSetParent* fdSet = nullptr;
if (!fds.IsEmpty()) {
Blob<Parent>* blob = static_cast<Blob<Parent>*>(mBlobActor);
MOZ_ASSERT(blob->Manager());
fdSet = blob->Manager()->SendPFileDescriptorSetConstructor(fds[0]);
if (fdSet) {
for (uint32_t index = 1; index < fds.Length(); index++) {
unused << fdSet->SendAddFileDescriptor(fds[index]);
}
}
}
OptionalFileDescriptorSet optionalFDs;
if (fdSet) {
optionalFDs = fdSet;
} else {
optionalFDs = mozilla::void_t();
}
unused << mStreamActor->Send__delete__(mStreamActor, params, optionalFDs);
mBlobActor->NoteRunnableCompleted(this);
@ -1094,8 +1164,9 @@ NS_IMETHODIMP
RemoteBlob<Parent>::GetInternalStream(nsIInputStream** aStream)
{
if (mInputStreamParams.type() != InputStreamParams::T__None) {
nsTArray<FileDescriptor> fds;
nsCOMPtr<nsIInputStream> realStream =
DeserializeInputStream(mInputStreamParams);
DeserializeInputStream(mInputStreamParams, fds);
if (!realStream) {
NS_WARNING("Failed to deserialize stream!");
return NS_ERROR_UNEXPECTED;
@ -1473,11 +1544,13 @@ Blob<Child>::RecvPBlobStreamConstructor(StreamType* aActor)
}
InputStreamParams params;
serializable->Serialize(params);
nsTArray<FileDescriptor> fds;
serializable->Serialize(params, fds);
MOZ_ASSERT(params.type() != InputStreamParams::T__None);
MOZ_ASSERT(fds.IsEmpty());
return aActor->Send__delete__(aActor, params);
return aActor->Send__delete__(aActor, params, mozilla::void_t());
}
BlobTraits<Parent>::StreamType*

View File

@ -157,6 +157,7 @@ template <ActorFlavorEnum ActorFlavor>
class Blob : public BlobTraits<ActorFlavor>::BaseType
{
friend class RemoteBlob<ActorFlavor>;
friend class BlobTraits<ActorFlavor>::BaseType;
public:
typedef typename BlobTraits<ActorFlavor>::ConcreteContentManagerType ContentManager;

View File

@ -14,6 +14,7 @@
#include "ContentChild.h"
#include "CrashReporterChild.h"
#include "FileDescriptorSetChild.h"
#include "TabChild.h"
#include "mozilla/Attributes.h"
@ -798,6 +799,18 @@ ContentChild::RecvPBrowserConstructor(PBrowserChild* actor,
return true;
}
PFileDescriptorSetChild*
ContentChild::AllocPFileDescriptorSetChild(const FileDescriptor& aFD)
{
return new FileDescriptorSetChild(aFD);
}
bool
ContentChild::DeallocPFileDescriptorSetChild(PFileDescriptorSetChild* aActor)
{
delete static_cast<FileDescriptorSetChild*>(aActor);
return true;
}
bool
ContentChild::DeallocPBrowserChild(PBrowserChild* iframe)
@ -904,7 +917,9 @@ ContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
NS_ENSURE_SUCCESS(rv, nullptr);
InputStreamParams inputStreamParams;
SerializeInputStream(stream, inputStreamParams);
nsTArray<mozilla::ipc::FileDescriptor> fds;
SerializeInputStream(stream, inputStreamParams, fds);
MOZ_ASSERT(fds.IsEmpty());
params.optionalInputStreamParams() = inputStreamParams;

View File

@ -40,6 +40,7 @@ class PrefObserver;
class ConsoleListener;
class PStorageChild;
class ClonedMessageData;
class PFileDescriptorSetChild;
class ContentChild : public PContentChild
{
@ -271,6 +272,12 @@ public:
BlobChild* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
virtual PFileDescriptorSetChild*
AllocPFileDescriptorSetChild(const FileDescriptor&) MOZ_OVERRIDE;
virtual bool
DeallocPFileDescriptorSetChild(PFileDescriptorSetChild*) MOZ_OVERRIDE;
protected:
virtual bool RecvPBrowserConstructor(PBrowserChild* actor,
const IPCTabContext& context,

View File

@ -34,6 +34,7 @@
#include "mozilla/dom/asmjscache/AsmJSCache.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ExternalHelperAppParent.h"
#include "mozilla/dom/PFileDescriptorSetParent.h"
#include "mozilla/dom/PMemoryReportRequestParent.h"
#include "mozilla/dom/power/PowerManagerService.h"
#include "mozilla/dom/DOMStorageIPC.h"
@ -293,6 +294,19 @@ MaybeTestPBackground()
namespace mozilla {
namespace dom {
namespace {
// The parent side of FileDescriptorSet doesn't need to do anything, really.
class FileDescriptorSetParent MOZ_FINAL: public PFileDescriptorSetParent
{
friend class mozilla::dom::ContentParent;
FileDescriptorSetParent() { }
~FileDescriptorSetParent() { }
};
} // anonymous namespace
#define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
class MemoryReportRequestParent : public PMemoryReportRequestParent
@ -3237,7 +3251,10 @@ ContentParent::RecvKeywordToURI(const nsCString& aKeyword, OptionalInputStreamPa
return true;
}
SerializeInputStream(postData, *aPostData);
nsTArray<mozilla::ipc::FileDescriptor> fds;
SerializeInputStream(postData, *aPostData, fds);
MOZ_ASSERT(fds.IsEmpty());
SerializeURI(uri, *aURI);
return true;
}
@ -3351,6 +3368,19 @@ ContentParent::RecvBackUpXResources(const FileDescriptor& aXSocketFd)
return true;
}
PFileDescriptorSetParent*
ContentParent::AllocPFileDescriptorSetParent(const FileDescriptor& /* aFD */)
{
return new FileDescriptorSetParent();
}
bool
ContentParent::DeallocPFileDescriptorSetParent(PFileDescriptorSetParent* aActor)
{
delete aActor;
return true;
}
} // namespace dom
} // namespace mozilla

View File

@ -57,6 +57,7 @@ class PStorageParent;
class ClonedMessageData;
class MemoryReport;
class TabContext;
class PFileDescriptorSetParent;
class ContentParent : public PContentParent
, public nsIObserver
@ -535,6 +536,12 @@ private:
virtual bool
RecvBackUpXResources(const FileDescriptor& aXSocketFd) MOZ_OVERRIDE;
virtual PFileDescriptorSetParent*
AllocPFileDescriptorSetParent(const mozilla::ipc::FileDescriptor&) MOZ_OVERRIDE;
virtual bool
DeallocPFileDescriptorSetParent(PFileDescriptorSetParent*) MOZ_OVERRIDE;
// If you add strong pointers to cycle collected objects here, be sure to
// release these objects in ShutDownProcess. See the comment there for more
// details.

View File

@ -0,0 +1,63 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_FileDescriptorSetChild_h__
#define mozilla_dom_FileDescriptorSetChild_h__
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/PFileDescriptorSetChild.h"
#include "nsTArray.h"
namespace mozilla {
namespace ipc {
class FileDescriptor;
} // namespace ipc
namespace dom {
class ContentChild;
class FileDescriptorSetChild MOZ_FINAL: public PFileDescriptorSetChild
{
friend class ContentChild;
public:
typedef mozilla::ipc::FileDescriptor FileDescriptor;
void
ForgetFileDescriptors(nsTArray<FileDescriptor>& aFileDescriptors)
{
aFileDescriptors.Clear();
mFileDescriptors.SwapElements(aFileDescriptors);
}
private:
FileDescriptorSetChild(const FileDescriptor& aFileDescriptor)
{
mFileDescriptors.AppendElement(aFileDescriptor);
}
~FileDescriptorSetChild()
{
MOZ_ASSERT(mFileDescriptors.IsEmpty());
}
virtual bool
RecvAddFileDescriptor(const FileDescriptor& aFileDescriptor) MOZ_OVERRIDE
{
mFileDescriptors.AppendElement(aFileDescriptor);
return true;
}
nsAutoTArray<FileDescriptor, 1> mFileDescriptors;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_FileDescriptorSetChild_h__

View File

@ -3,17 +3,26 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PBlob;
include protocol PFileDescriptorSet;
include InputStreamParams;
using mozilla::void_t from "ipc/IPCMessageUtils.h";
namespace mozilla {
namespace dom {
union OptionalFileDescriptorSet
{
PFileDescriptorSet;
void_t;
};
protocol PBlobStream
{
manager PBlob;
both:
__delete__(InputStreamParams params);
__delete__(InputStreamParams params, OptionalFileDescriptorSet fds);
};
} // namespace dom

View File

@ -13,6 +13,7 @@ include protocol PCompositor;
include protocol PCrashReporter;
include protocol PExternalHelperApp;
include protocol PDeviceStorageRequest;
include protocol PFileDescriptorSet;
include protocol PFMRadio;
include protocol PFileSystemRequest;
include protocol PHal;
@ -258,6 +259,7 @@ intr protocol PContent
manages PDeviceStorageRequest;
manages PFileSystemRequest;
manages PExternalHelperApp;
manages PFileDescriptorSet;
manages PFMRadio;
manages PHal;
manages PIndexedDB;
@ -310,6 +312,8 @@ child:
PMemoryReportRequest(uint32_t generation, bool minimizeMemoryUsage, nsString DMDDumpIdent);
PFileDescriptorSet(FileDescriptor fd);
/**
* Notify the AudioChannelService in the child processes.
*/

View File

@ -0,0 +1,22 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PContent;
namespace mozilla {
namespace dom {
protocol PFileDescriptorSet
{
manager PContent;
child:
AddFileDescriptor(FileDescriptor fd);
parent:
__delete__();
};
} // namespace dom
} // namespace mozilla

View File

@ -23,6 +23,7 @@ EXPORTS.mozilla.dom += [
'ContentProcess.h',
'CrashReporterChild.h',
'CrashReporterParent.h',
'FileDescriptorSetChild.h',
'FilePickerParent.h',
'PermissionMessageUtils.h',
'StructuredCloneUtils.h',
@ -44,6 +45,7 @@ UNIFIED_SOURCES += [
'ContentParent.cpp',
'ContentProcess.cpp',
'CrashReporterParent.cpp',
'PFileDescriptorSet.ipdl',
'FilePickerParent.cpp',
'PermissionMessageUtils.cpp',
'PreallocatedProcessManager.cpp',

View File

@ -696,8 +696,9 @@ struct ParamTraitsIPC<base::FileDescriptor> {
WriteParam(m, valid);
if (valid) {
if (!m->WriteFileDescriptor(p))
NOTREACHED();
if (!m->WriteFileDescriptor(p)) {
NOTREACHED() << "Too many file descriptors for one message!";
}
}
}
static bool Read(const Message* m, void** iter, param_type* r) {

View File

@ -16,7 +16,7 @@ struct StringInputStreamParams
struct FileInputStreamParams
{
FileDescriptor file;
uint32_t fileDescriptorIndex;
int32_t behaviorFlags;
int32_t ioFlags;
};

View File

@ -20,7 +20,6 @@
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
using namespace mozilla::ipc;
using mozilla::dom::BlobChild;
using mozilla::dom::BlobParent;
@ -40,7 +39,8 @@ namespace ipc {
void
SerializeInputStream(nsIInputStream* aInputStream,
InputStreamParams& aParams)
InputStreamParams& aParams,
nsTArray<FileDescriptor>& aFileDescriptors)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aInputStream);
@ -51,7 +51,7 @@ SerializeInputStream(nsIInputStream* aInputStream,
MOZ_CRASH("Input stream is not serializable!");
}
serializable->Serialize(aParams);
serializable->Serialize(aParams, aFileDescriptors);
if (aParams.type() == InputStreamParams::T__None) {
MOZ_CRASH("Serialize failed!");
@ -60,13 +60,14 @@ SerializeInputStream(nsIInputStream* aInputStream,
void
SerializeInputStream(nsIInputStream* aInputStream,
OptionalInputStreamParams& aParams)
OptionalInputStreamParams& aParams,
nsTArray<FileDescriptor>& aFileDescriptors)
{
MOZ_ASSERT(NS_IsMainThread());
if (aInputStream) {
InputStreamParams params;
SerializeInputStream(aInputStream, params);
SerializeInputStream(aInputStream, params, aFileDescriptors);
aParams = params;
}
else {
@ -75,7 +76,8 @@ SerializeInputStream(nsIInputStream* aInputStream,
}
already_AddRefed<nsIInputStream>
DeserializeInputStream(const InputStreamParams& aParams)
DeserializeInputStream(const InputStreamParams& aParams,
const nsTArray<FileDescriptor>& aFileDescriptors)
{
MOZ_ASSERT(NS_IsMainThread());
@ -136,7 +138,7 @@ DeserializeInputStream(const InputStreamParams& aParams)
MOZ_ASSERT(serializable);
if (!serializable->Deserialize(aParams)) {
if (!serializable->Deserialize(aParams, aFileDescriptors)) {
MOZ_ASSERT(false, "Deserialize failed!");
return nullptr;
}
@ -148,7 +150,8 @@ DeserializeInputStream(const InputStreamParams& aParams)
}
already_AddRefed<nsIInputStream>
DeserializeInputStream(const OptionalInputStreamParams& aParams)
DeserializeInputStream(const OptionalInputStreamParams& aParams,
const nsTArray<FileDescriptor>& aFileDescriptors)
{
MOZ_ASSERT(NS_IsMainThread());
@ -160,7 +163,8 @@ DeserializeInputStream(const OptionalInputStreamParams& aParams)
break;
case OptionalInputStreamParams::TInputStreamParams:
stream = DeserializeInputStream(aParams.get_InputStreamParams());
stream = DeserializeInputStream(aParams.get_InputStreamParams(),
aFileDescriptors);
break;
default:

View File

@ -8,23 +8,30 @@
#include "mozilla/ipc/InputStreamParams.h"
#include "nsCOMPtr.h"
#include "nsIInputStream.h"
#include "nsTArray.h"
namespace mozilla {
namespace ipc {
void
SerializeInputStream(nsIInputStream* aInputStream,
InputStreamParams& aParams);
class FileDescriptor;
void
SerializeInputStream(nsIInputStream* aInputStream,
OptionalInputStreamParams& aParams);
InputStreamParams& aParams,
nsTArray<FileDescriptor>& aFileDescriptors);
void
SerializeInputStream(nsIInputStream* aInputStream,
OptionalInputStreamParams& aParams,
nsTArray<FileDescriptor>& aFileDescriptors);
already_AddRefed<nsIInputStream>
DeserializeInputStream(const InputStreamParams& aParams);
DeserializeInputStream(const InputStreamParams& aParams,
const nsTArray<FileDescriptor>& aFileDescriptors);
already_AddRefed<nsIInputStream>
DeserializeInputStream(const OptionalInputStreamParams& aParams);
DeserializeInputStream(const OptionalInputStreamParams& aParams,
const nsTArray<FileDescriptor>& aFileDescriptors);
} // namespace ipc
} // namespace mozilla

View File

@ -8,50 +8,80 @@
#include "nsISupports.h"
#include "mozilla/Attributes.h"
struct nsTArrayDefaultAllocator;
template <class> class nsTArray;
namespace mozilla {
namespace ipc {
class FileDescriptor;
class InputStreamParams;
}
}
} // namespace ipc
} // namespace mozilla
#define NS_IIPCSERIALIZABLEINPUTSTREAM_IID \
{0x1f56a3f8, 0xc413, 0x4274, {0x88, 0xe6, 0x68, 0x50, 0x9d, 0xf8, 0x85, 0x2d}}
{0xb0211b14, 0xea6d, 0x40d4, {0x87, 0xb5, 0x7b, 0xe3, 0xdf, 0xac, 0x09, 0xd1}}
class NS_NO_VTABLE nsIIPCSerializableInputStream : public nsISupports
{
public:
typedef nsTArray<mozilla::ipc::FileDescriptor>
FileDescriptorArray;
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IIPCSERIALIZABLEINPUTSTREAM_IID)
virtual void
Serialize(mozilla::ipc::InputStreamParams& aParams) = 0;
Serialize(mozilla::ipc::InputStreamParams& aParams,
FileDescriptorArray& aFileDescriptors) = 0;
virtual bool
Deserialize(const mozilla::ipc::InputStreamParams& aParams) = 0;
Deserialize(const mozilla::ipc::InputStreamParams& aParams,
const FileDescriptorArray& aFileDescriptors) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIIPCSerializableInputStream,
NS_IIPCSERIALIZABLEINPUTSTREAM_IID)
#define NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM \
virtual void \
Serialize(mozilla::ipc::InputStreamParams&) MOZ_OVERRIDE; \
virtual bool \
Deserialize(const mozilla::ipc::InputStreamParams&) MOZ_OVERRIDE;
#define NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM \
virtual void \
Serialize(mozilla::ipc::InputStreamParams&, \
FileDescriptorArray&) MOZ_OVERRIDE; \
\
virtual bool \
Deserialize(const mozilla::ipc::InputStreamParams&, \
const FileDescriptorArray&) MOZ_OVERRIDE;
#define NS_FORWARD_NSIIPCSERIALIZABLEINPUTSTREAM(_to) \
virtual void \
Serialize(mozilla::ipc::InputStreamParams& aParams) MOZ_OVERRIDE \
{ _to Serialize(aParams); } \
virtual bool \
Deserialize(const mozilla::ipc::InputStreamParams& aParams) MOZ_OVERRIDE \
{ return _to Deserialize(aParams); }
#define NS_FORWARD_NSIIPCSERIALIZABLEINPUTSTREAM(_to) \
virtual void \
Serialize(mozilla::ipc::InputStreamParams& aParams, \
FileDescriptorArray& aFileDescriptors) MOZ_OVERRIDE \
{ \
_to Serialize(aParams, aFileDescriptors); \
} \
\
virtual bool \
Deserialize(const mozilla::ipc::InputStreamParams& aParams, \
const FileDescriptorArray& aFileDescriptors) MOZ_OVERRIDE \
{ \
return _to Deserialize(aParams, aFileDescriptors); \
}
#define NS_FORWARD_SAFE_NSIIPCSERIALIZABLEINPUTSTREAM(_to) \
virtual void \
Serialize(mozilla::ipc::InputStreamParams& aParams) MOZ_OVERRIDE \
{ if (_to) { _to->Serialize(aParams); } } \
virtual bool \
Deserialize(const mozilla::ipc::InputStreamParams& aParams) MOZ_OVERRIDE \
{ if (_to) { return _to->Deserialize(aParams); } return false; }
#define NS_FORWARD_SAFE_NSIIPCSERIALIZABLEINPUTSTREAM(_to) \
virtual void \
Serialize(mozilla::ipc::InputStreamParams& aParams, \
FileDescriptorArray& aFileDescriptors) MOZ_OVERRIDE \
{ \
if (_to) { \
_to->Serialize(aParams, aFileDescriptors); \
} \
} \
\
virtual bool \
Deserialize(const mozilla::ipc::InputStreamParams& aParams, \
const FileDescriptorArray& aFileDescriptors) MOZ_OVERRIDE \
{ \
return _to ? _to->Deserialize(aParams, aFileDescriptors) : false; \
}
#endif // mozilla_ipc_nsIIPCSerializableInputStream_h

View File

@ -486,20 +486,17 @@ nsBufferedInputStream::GetUnbufferedStream(nsISupports* *aStream)
}
void
nsBufferedInputStream::Serialize(InputStreamParams& aParams)
nsBufferedInputStream::Serialize(InputStreamParams& aParams,
FileDescriptorArray& aFileDescriptors)
{
BufferedInputStreamParams params;
if (mStream) {
nsCOMPtr<nsIIPCSerializableInputStream> stream =
do_QueryInterface(mStream);
NS_ASSERTION(stream, "Wrapped stream is not serializable!");
nsCOMPtr<nsIInputStream> stream = do_QueryInterface(mStream);
MOZ_ASSERT(stream);
InputStreamParams wrappedParams;
stream->Serialize(wrappedParams);
NS_ASSERTION(wrappedParams.type() != InputStreamParams::T__None,
"Wrapped stream failed to serialize!");
SerializeInputStream(stream, wrappedParams, aFileDescriptors);
params.optionalStream() = wrappedParams;
}
@ -513,7 +510,8 @@ nsBufferedInputStream::Serialize(InputStreamParams& aParams)
}
bool
nsBufferedInputStream::Deserialize(const InputStreamParams& aParams)
nsBufferedInputStream::Deserialize(const InputStreamParams& aParams,
const FileDescriptorArray& aFileDescriptors)
{
if (aParams.type() != InputStreamParams::TBufferedInputStreamParams) {
NS_ERROR("Received unknown parameters from the other process!");
@ -526,7 +524,8 @@ nsBufferedInputStream::Deserialize(const InputStreamParams& aParams)
nsCOMPtr<nsIInputStream> stream;
if (wrappedParams.type() == OptionalInputStreamParams::TInputStreamParams) {
stream = DeserializeInputStream(wrappedParams.get_InputStreamParams());
stream = DeserializeInputStream(wrappedParams.get_InputStreamParams(),
aFileDescriptors);
if (!stream) {
NS_WARNING("Failed to deserialize wrapped stream!");
return false;

View File

@ -27,6 +27,7 @@
typedef mozilla::ipc::FileDescriptor::PlatformHandleType FileHandleType;
using namespace mozilla::ipc;
using mozilla::DebugOnly;
////////////////////////////////////////////////////////////////////////////////
// nsFileStreamBase
@ -533,7 +534,8 @@ nsFileInputStream::Available(uint64_t *aResult)
}
void
nsFileInputStream::Serialize(InputStreamParams& aParams)
nsFileInputStream::Serialize(InputStreamParams& aParams,
FileDescriptorArray& aFileDescriptors)
{
FileInputStreamParams params;
@ -541,9 +543,10 @@ nsFileInputStream::Serialize(InputStreamParams& aParams)
FileHandleType fd = FileHandleType(PR_FileDesc2NativeHandle(mFD));
NS_ASSERTION(fd, "This should never be null!");
params.file() = FileDescriptor(fd);
NS_ASSERTION(params.file().IsValid(),
"Sending an invalid file descriptor!");
DebugOnly<FileDescriptor*> dbgFD = aFileDescriptors.AppendElement(fd);
NS_ASSERTION(dbgFD->IsValid(), "Sending an invalid file descriptor!");
params.fileDescriptorIndex() = aFileDescriptors.Length() - 1;
} else {
NS_WARNING("This file has not been opened (or could not be opened). "
"Sending an invalid file descriptor to the other process!");
@ -570,7 +573,8 @@ nsFileInputStream::Serialize(InputStreamParams& aParams)
}
bool
nsFileInputStream::Deserialize(const InputStreamParams& aParams)
nsFileInputStream::Deserialize(const InputStreamParams& aParams,
const FileDescriptorArray& aFileDescriptors)
{
NS_ASSERTION(!mFD, "Already have a file descriptor?!");
NS_ASSERTION(!mDeferredOpen, "Deferring open?!");
@ -584,8 +588,15 @@ nsFileInputStream::Deserialize(const InputStreamParams& aParams)
const FileInputStreamParams& params = aParams.get_FileInputStreamParams();
const FileDescriptor& fd = params.file();
NS_WARN_IF_FALSE(fd.IsValid(), "Received an invalid file descriptor!");
uint32_t fileDescriptorIndex = params.fileDescriptorIndex();
FileDescriptor fd;
if (fileDescriptorIndex < aFileDescriptors.Length()) {
fd = aFileDescriptors[fileDescriptorIndex];
NS_WARN_IF_FALSE(fd.IsValid(), "Received an invalid file descriptor!");
} else {
NS_WARNING("Received a bad file descriptor index!");
}
if (fd.IsValid()) {
PRFileDesc* fileDesc = PR_ImportFile(PROsfd(fd.PlatformHandle()));
@ -726,16 +737,12 @@ nsPartialFileInputStream::Seek(int32_t aWhence, int64_t aOffset)
}
void
nsPartialFileInputStream::Serialize(InputStreamParams& aParams)
nsPartialFileInputStream::Serialize(InputStreamParams& aParams,
FileDescriptorArray& aFileDescriptors)
{
// Serialize the base class first.
InputStreamParams fileParams;
nsFileInputStream::Serialize(fileParams);
if (fileParams.type() != InputStreamParams::TFileInputStreamParams) {
NS_ERROR("Base class serialize failed!");
return;
}
nsFileInputStream::Serialize(fileParams, aFileDescriptors);
PartialFileInputStreamParams params;
@ -747,7 +754,9 @@ nsPartialFileInputStream::Serialize(InputStreamParams& aParams)
}
bool
nsPartialFileInputStream::Deserialize(const InputStreamParams& aParams)
nsPartialFileInputStream::Deserialize(
const InputStreamParams& aParams,
const FileDescriptorArray& aFileDescriptors)
{
NS_ASSERTION(!mFD, "Already have a file descriptor?!");
NS_ASSERTION(!mStart, "Already have a start?!");
@ -755,7 +764,7 @@ nsPartialFileInputStream::Deserialize(const InputStreamParams& aParams)
NS_ASSERTION(!mPosition, "Already have a position?!");
if (aParams.type() != InputStreamParams::TPartialFileInputStreamParams) {
NS_ERROR("Received unknown parameters from the other process!");
NS_WARNING("Received unknown parameters from the other process!");
return false;
}
@ -764,8 +773,8 @@ nsPartialFileInputStream::Deserialize(const InputStreamParams& aParams)
// Deserialize the base class first.
InputStreamParams fileParams(params.fileStreamParams());
if (!nsFileInputStream::Deserialize(fileParams)) {
NS_ERROR("Base class deserialize failed!");
if (!nsFileInputStream::Deserialize(fileParams, aFileDescriptors)) {
NS_WARNING("Base class deserialize failed!");
return false;
}

View File

@ -295,17 +295,17 @@ nsMIMEInputStreamConstructor(nsISupports *outer, REFNSIID iid, void **result)
}
void
nsMIMEInputStream::Serialize(InputStreamParams& aParams)
nsMIMEInputStream::Serialize(InputStreamParams& aParams,
FileDescriptorArray& aFileDescriptors)
{
MIMEInputStreamParams params;
if (mData) {
nsCOMPtr<nsIIPCSerializableInputStream> stream =
do_QueryInterface(mData);
NS_ASSERTION(stream, "Wrapped stream is not serializable!");
nsCOMPtr<nsIInputStream> stream = do_QueryInterface(mStream);
MOZ_ASSERT(stream);
InputStreamParams wrappedParams;
stream->Serialize(wrappedParams);
SerializeInputStream(stream, wrappedParams, aFileDescriptors);
NS_ASSERTION(wrappedParams.type() != InputStreamParams::T__None,
"Wrapped stream failed to serialize!");
@ -325,7 +325,8 @@ nsMIMEInputStream::Serialize(InputStreamParams& aParams)
}
bool
nsMIMEInputStream::Deserialize(const InputStreamParams& aParams)
nsMIMEInputStream::Deserialize(const InputStreamParams& aParams,
const FileDescriptorArray& aFileDescriptors)
{
if (aParams.type() != InputStreamParams::TMIMEInputStreamParams) {
NS_ERROR("Received unknown parameters from the other process!");
@ -348,7 +349,8 @@ nsMIMEInputStream::Deserialize(const InputStreamParams& aParams)
nsCOMPtr<nsIInputStream> stream;
if (wrappedParams.type() == OptionalInputStreamParams::TInputStreamParams) {
stream = DeserializeInputStream(wrappedParams.get_InputStreamParams());
stream = DeserializeInputStream(wrappedParams.get_InputStreamParams(),
aFileDescriptors);
if (!stream) {
NS_WARNING("Failed to deserialize wrapped stream!");
return false;

View File

@ -179,7 +179,10 @@ FTPChannelChild::AsyncOpen(::nsIStreamListener* listener, nsISupports* aContext)
mLoadGroup->AddRequest(this, nullptr);
OptionalInputStreamParams uploadStream;
SerializeInputStream(mUploadStream, uploadStream);
nsTArray<mozilla::ipc::FileDescriptor> fds;
SerializeInputStream(mUploadStream, uploadStream, fds);
MOZ_ASSERT(fds.IsEmpty());
FTPChannelOpenArgs openArgs;
SerializeURI(nsBaseChannel::URI(), openArgs.uri());

View File

@ -124,7 +124,8 @@ FTPChannelParent::DoAsyncOpen(const URIParams& aURI,
if (NS_FAILED(rv))
return SendFailedAsyncOpen(rv);
nsCOMPtr<nsIInputStream> upload = DeserializeInputStream(aUploadStream);
nsTArray<mozilla::ipc::FileDescriptor> fds;
nsCOMPtr<nsIInputStream> upload = DeserializeInputStream(aUploadStream, fds);
if (upload) {
// contentType and contentLength are ignored
rv = mChannel->SetUploadStream(upload, EmptyCString(), 0);

View File

@ -1197,7 +1197,11 @@ HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
openArgs.loadFlags() = mLoadFlags;
openArgs.requestHeaders() = mClientSetRequestHeaders;
openArgs.requestMethod() = mRequestHead.Method();
SerializeInputStream(mUploadStream, openArgs.uploadStream());
nsTArray<mozilla::ipc::FileDescriptor> fds;
SerializeInputStream(mUploadStream, openArgs.uploadStream(), fds);
MOZ_ASSERT(fds.IsEmpty());
openArgs.uploadStreamHasHeaders() = mUploadStreamHasHeaders;
openArgs.priority() = mPriority;
openArgs.redirectionLimit() = mRedirectionLimit;

View File

@ -219,7 +219,8 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
mChannel->SetRequestMethod(nsDependentCString(requestMethod.get()));
nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(uploadStream);
nsTArray<mozilla::ipc::FileDescriptor> fds;
nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(uploadStream, fds);
if (stream) {
mChannel->InternalSetUploadStream(stream);
mChannel->SetUploadStreamHasHeaders(uploadStreamHasHeaders);

View File

@ -397,7 +397,10 @@ WebSocketChannelChild::SendBinaryStream(nsIInputStream *aStream,
LOG(("WebSocketChannelChild::SendBinaryStream() %p\n", this));
OptionalInputStreamParams stream;
SerializeInputStream(aStream, stream);
nsTArray<mozilla::ipc::FileDescriptor> fds;
SerializeInputStream(aStream, stream, fds);
MOZ_ASSERT(fds.IsEmpty());
if (!mIPCOpen || !SendSendBinaryStream(stream, aLength))
return NS_ERROR_UNEXPECTED;

View File

@ -148,7 +148,8 @@ WebSocketChannelParent::RecvSendBinaryStream(const InputStreamParams& aStream,
{
LOG(("WebSocketChannelParent::RecvSendBinaryStream() %p\n", this));
if (mChannel) {
nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(aStream);
nsTArray<mozilla::ipc::FileDescriptor> fds;
nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(aStream, fds);
if (!stream) {
return false;
}

View File

@ -629,7 +629,8 @@ nsMultiplexInputStreamConstructor(nsISupports *outer,
}
void
nsMultiplexInputStream::Serialize(InputStreamParams& aParams)
nsMultiplexInputStream::Serialize(InputStreamParams& aParams,
FileDescriptorArray& aFileDescriptors)
{
MultiplexInputStreamParams params;
@ -640,20 +641,11 @@ nsMultiplexInputStream::Serialize(InputStreamParams& aParams)
streams.SetCapacity(streamCount);
for (uint32_t index = 0; index < streamCount; index++) {
nsCOMPtr<nsIIPCSerializableInputStream> serializable =
do_QueryInterface(mStreams[index]);
NS_ASSERTION(serializable, "Child stream isn't serializable!");
InputStreamParams childStreamParams;
SerializeInputStream(mStreams[index], childStreamParams,
aFileDescriptors);
if (serializable) {
InputStreamParams childStreamParams;
serializable->Serialize(childStreamParams);
NS_ASSERTION(childStreamParams.type() !=
InputStreamParams::T__None,
"Serialize failed!");
streams.AppendElement(childStreamParams);
}
streams.AppendElement(childStreamParams);
}
}
@ -665,7 +657,8 @@ nsMultiplexInputStream::Serialize(InputStreamParams& aParams)
}
bool
nsMultiplexInputStream::Deserialize(const InputStreamParams& aParams)
nsMultiplexInputStream::Deserialize(const InputStreamParams& aParams,
const FileDescriptorArray& aFileDescriptors)
{
if (aParams.type() !=
InputStreamParams::TMultiplexInputStreamParams) {
@ -681,7 +674,7 @@ nsMultiplexInputStream::Deserialize(const InputStreamParams& aParams)
uint32_t streamCount = streams.Length();
for (uint32_t index = 0; index < streamCount; index++) {
nsCOMPtr<nsIInputStream> stream =
DeserializeInputStream(streams[index]);
DeserializeInputStream(streams[index], aFileDescriptors);
if (!stream) {
NS_WARNING("Deserialize failed!");
return false;

View File

@ -294,7 +294,8 @@ nsStringInputStream::SetEOF()
}
void
nsStringInputStream::Serialize(InputStreamParams& aParams)
nsStringInputStream::Serialize(InputStreamParams& aParams,
FileDescriptorArray& /* aFDs */)
{
StringInputStreamParams params;
params.data() = PromiseFlatCString(mData);
@ -302,7 +303,8 @@ nsStringInputStream::Serialize(InputStreamParams& aParams)
}
bool
nsStringInputStream::Deserialize(const InputStreamParams& aParams)
nsStringInputStream::Deserialize(const InputStreamParams& aParams,
const FileDescriptorArray& /* aFDs */)
{
if (aParams.type() != InputStreamParams::TStringInputStreamParams) {
NS_ERROR("Received unknown parameters from the other process!");