2016-05-28 00:54:31 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2016-05-15 20:32:09 +03:00
|
|
|
/* 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 "IPCStreamUtils.h"
|
|
|
|
|
|
|
|
#include "nsIIPCSerializableInputStream.h"
|
|
|
|
|
|
|
|
#include "mozilla/Assertions.h"
|
2018-02-23 23:26:38 +03:00
|
|
|
#include "mozilla/dom/ContentChild.h"
|
|
|
|
#include "mozilla/dom/ContentParent.h"
|
2016-05-15 20:32:09 +03:00
|
|
|
#include "mozilla/dom/File.h"
|
|
|
|
#include "mozilla/ipc/FileDescriptorSetChild.h"
|
|
|
|
#include "mozilla/ipc/FileDescriptorSetParent.h"
|
2016-08-05 22:00:19 +03:00
|
|
|
#include "mozilla/ipc/InputStreamUtils.h"
|
2016-05-15 20:32:09 +03:00
|
|
|
#include "mozilla/ipc/PBackgroundChild.h"
|
2016-08-05 22:00:19 +03:00
|
|
|
#include "mozilla/ipc/PBackgroundParent.h"
|
2016-08-23 07:09:32 +03:00
|
|
|
#include "mozilla/Unused.h"
|
2017-04-11 00:50:00 +03:00
|
|
|
#include "nsNetCID.h"
|
2016-05-15 20:32:09 +03:00
|
|
|
|
2017-04-11 00:50:00 +03:00
|
|
|
using namespace mozilla::dom;
|
|
|
|
|
2016-05-15 20:32:09 +03:00
|
|
|
namespace mozilla {
|
|
|
|
namespace ipc {
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
// These serialization and cleanup functions could be externally exposed. For
|
|
|
|
// now, though, keep them private to encourage use of the safer RAII
|
|
|
|
// AutoIPCStream class.
|
|
|
|
|
|
|
|
template <typename M>
|
2017-03-14 14:29:43 +03:00
|
|
|
bool SerializeInputStreamWithFdsChild(nsIIPCSerializableInputStream* aStream,
|
2019-01-28 12:48:35 +03:00
|
|
|
IPCStream& aValue, bool aDelayedStart,
|
|
|
|
M* aManager) {
|
2017-03-14 14:29:43 +03:00
|
|
|
MOZ_RELEASE_ASSERT(aStream);
|
2016-05-15 20:32:09 +03:00
|
|
|
MOZ_ASSERT(aManager);
|
|
|
|
|
|
|
|
AutoTArray<FileDescriptor, 4> fds;
|
2019-01-28 12:49:13 +03:00
|
|
|
aStream->Serialize(aValue.stream(), fds, aDelayedStart, aManager);
|
2016-05-15 20:32:09 +03:00
|
|
|
|
2019-01-28 12:49:13 +03:00
|
|
|
if (aValue.stream().type() == InputStreamParams::T__None) {
|
2016-05-15 20:32:09 +03:00
|
|
|
MOZ_CRASH("Serialize failed!");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fds.IsEmpty()) {
|
2019-01-28 12:49:13 +03:00
|
|
|
aValue.optionalFds() = void_t();
|
2016-05-15 20:32:09 +03:00
|
|
|
} else {
|
|
|
|
PFileDescriptorSetChild* fdSet =
|
|
|
|
aManager->SendPFileDescriptorSetConstructor(fds[0]);
|
|
|
|
for (uint32_t i = 1; i < fds.Length(); ++i) {
|
|
|
|
Unused << fdSet->SendAddFileDescriptor(fds[i]);
|
|
|
|
}
|
|
|
|
|
2019-01-28 12:49:13 +03:00
|
|
|
aValue.optionalFds() = fdSet;
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
2017-03-14 14:29:43 +03:00
|
|
|
|
|
|
|
return true;
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename M>
|
2017-03-14 14:29:43 +03:00
|
|
|
bool SerializeInputStreamWithFdsParent(nsIIPCSerializableInputStream* aStream,
|
2019-01-28 12:48:35 +03:00
|
|
|
IPCStream& aValue, bool aDelayedStart,
|
|
|
|
M* aManager) {
|
2017-03-14 14:29:43 +03:00
|
|
|
MOZ_RELEASE_ASSERT(aStream);
|
2016-05-15 20:32:09 +03:00
|
|
|
MOZ_ASSERT(aManager);
|
|
|
|
|
|
|
|
AutoTArray<FileDescriptor, 4> fds;
|
2019-01-28 12:49:13 +03:00
|
|
|
aStream->Serialize(aValue.stream(), fds, aDelayedStart, aManager);
|
2016-05-15 20:32:09 +03:00
|
|
|
|
2019-01-28 12:49:13 +03:00
|
|
|
if (aValue.stream().type() == InputStreamParams::T__None) {
|
2016-05-15 20:32:09 +03:00
|
|
|
MOZ_CRASH("Serialize failed!");
|
|
|
|
}
|
|
|
|
|
2019-01-28 12:49:13 +03:00
|
|
|
aValue.optionalFds() = void_t();
|
2016-05-15 20:32:09 +03:00
|
|
|
if (!fds.IsEmpty()) {
|
|
|
|
PFileDescriptorSetParent* fdSet =
|
|
|
|
aManager->SendPFileDescriptorSetConstructor(fds[0]);
|
|
|
|
for (uint32_t i = 1; i < fds.Length(); ++i) {
|
|
|
|
if (NS_WARN_IF(!fdSet->SendAddFileDescriptor(fds[i]))) {
|
|
|
|
Unused << PFileDescriptorSetParent::Send__delete__(fdSet);
|
|
|
|
fdSet = nullptr;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fdSet) {
|
2019-01-28 12:49:13 +03:00
|
|
|
aValue.optionalFds() = fdSet;
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
}
|
2017-03-14 14:29:43 +03:00
|
|
|
|
|
|
|
return true;
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
2017-03-09 16:11:21 +03:00
|
|
|
template <typename M>
|
2017-04-24 13:09:39 +03:00
|
|
|
bool SerializeInputStream(nsIInputStream* aStream, IPCStream& aValue,
|
|
|
|
M* aManager, bool aDelayedStart) {
|
2017-03-14 14:29:43 +03:00
|
|
|
MOZ_ASSERT(aStream);
|
|
|
|
MOZ_ASSERT(aManager);
|
|
|
|
|
2018-05-31 19:12:25 +03:00
|
|
|
// Let's try to take the length using InputStreamLengthHelper. If the length
|
|
|
|
// cannot be taken synchronously, and its length is needed, the stream needs
|
|
|
|
// to be fully copied in memory on the deserialization side.
|
|
|
|
int64_t length;
|
|
|
|
if (!InputStreamLengthHelper::GetSyncLength(aStream, &length)) {
|
|
|
|
length = -1;
|
|
|
|
}
|
|
|
|
|
2017-03-14 14:29:43 +03:00
|
|
|
// As a fallback, attempt to stream the data across using a IPCStream
|
|
|
|
// actor. For blocking streams, create a nonblocking pipe instead,
|
|
|
|
nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(aStream);
|
|
|
|
if (!asyncStream) {
|
|
|
|
const uint32_t kBufferSize = 32768; // matches IPCStream buffer size.
|
|
|
|
nsCOMPtr<nsIAsyncOutputStream> sink;
|
|
|
|
nsresult rv = NS_NewPipe2(getter_AddRefs(asyncStream), getter_AddRefs(sink),
|
|
|
|
true, false, kBufferSize, UINT32_MAX);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIEventTarget> target =
|
|
|
|
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
|
|
|
|
|
|
|
rv = NS_AsyncCopy(aStream, sink, target, NS_ASYNCCOPY_VIA_READSEGMENTS,
|
|
|
|
kBufferSize);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return false;
|
|
|
|
}
|
2017-03-09 16:11:21 +03:00
|
|
|
}
|
|
|
|
|
2017-03-14 14:29:43 +03:00
|
|
|
MOZ_ASSERT(asyncStream);
|
2017-04-24 13:09:39 +03:00
|
|
|
|
2019-01-28 12:49:13 +03:00
|
|
|
IPCRemoteStreamParams remoteStream;
|
2017-04-24 13:09:39 +03:00
|
|
|
remoteStream.delayedStart() = aDelayedStart;
|
2017-04-24 13:09:39 +03:00
|
|
|
remoteStream.stream() = IPCStreamSource::Create(asyncStream, aManager);
|
2018-05-31 19:12:25 +03:00
|
|
|
remoteStream.length() = length;
|
2019-01-28 12:49:13 +03:00
|
|
|
|
|
|
|
aValue.stream() = remoteStream;
|
|
|
|
aValue.optionalFds() = void_t();
|
2017-04-24 13:09:39 +03:00
|
|
|
|
2017-03-14 14:29:43 +03:00
|
|
|
return true;
|
2017-03-09 16:11:21 +03:00
|
|
|
}
|
|
|
|
|
2016-05-15 20:32:09 +03:00
|
|
|
template <typename M>
|
2017-03-14 14:29:43 +03:00
|
|
|
bool SerializeInputStreamChild(nsIInputStream* aStream, M* aManager,
|
|
|
|
IPCStream* aValue,
|
2017-04-24 13:09:39 +03:00
|
|
|
OptionalIPCStream* aOptionalValue,
|
|
|
|
bool aDelayedStart) {
|
2016-05-15 20:32:09 +03:00
|
|
|
MOZ_ASSERT(aStream);
|
|
|
|
MOZ_ASSERT(aManager);
|
2017-03-14 14:29:43 +03:00
|
|
|
MOZ_ASSERT(aValue || aOptionalValue);
|
2016-05-15 20:32:09 +03:00
|
|
|
|
|
|
|
nsCOMPtr<nsIIPCSerializableInputStream> serializable =
|
|
|
|
do_QueryInterface(aStream);
|
2017-03-14 14:29:43 +03:00
|
|
|
|
2019-01-28 12:48:35 +03:00
|
|
|
if (serializable) {
|
2017-03-14 14:29:43 +03:00
|
|
|
if (aValue) {
|
2019-01-28 12:48:35 +03:00
|
|
|
return SerializeInputStreamWithFdsChild(serializable, *aValue,
|
|
|
|
aDelayedStart, aManager);
|
2017-03-14 14:29:43 +03:00
|
|
|
}
|
2016-09-29 07:20:00 +03:00
|
|
|
|
2017-03-14 14:29:43 +03:00
|
|
|
return SerializeInputStreamWithFdsChild(serializable, *aOptionalValue,
|
2019-01-28 12:48:35 +03:00
|
|
|
aDelayedStart, aManager);
|
2016-09-29 07:20:00 +03:00
|
|
|
}
|
|
|
|
|
2017-03-14 14:29:43 +03:00
|
|
|
if (aValue) {
|
2017-04-24 13:09:39 +03:00
|
|
|
return SerializeInputStream(aStream, *aValue, aManager, aDelayedStart);
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
2017-03-14 14:29:43 +03:00
|
|
|
|
2017-04-24 13:09:39 +03:00
|
|
|
return SerializeInputStream(aStream, *aOptionalValue, aManager,
|
|
|
|
aDelayedStart);
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename M>
|
2017-03-14 14:29:43 +03:00
|
|
|
bool SerializeInputStreamParent(nsIInputStream* aStream, M* aManager,
|
|
|
|
IPCStream* aValue,
|
2017-04-24 13:09:39 +03:00
|
|
|
OptionalIPCStream* aOptionalValue,
|
|
|
|
bool aDelayedStart) {
|
2017-03-14 14:29:43 +03:00
|
|
|
MOZ_ASSERT(aStream);
|
|
|
|
MOZ_ASSERT(aManager);
|
|
|
|
MOZ_ASSERT(aValue || aOptionalValue);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIIPCSerializableInputStream> serializable =
|
|
|
|
do_QueryInterface(aStream);
|
|
|
|
|
2019-01-28 12:48:35 +03:00
|
|
|
if (serializable) {
|
2017-03-14 14:29:43 +03:00
|
|
|
if (aValue) {
|
2019-01-28 12:48:35 +03:00
|
|
|
return SerializeInputStreamWithFdsParent(serializable, *aValue,
|
|
|
|
aDelayedStart, aManager);
|
2017-03-14 14:29:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return SerializeInputStreamWithFdsParent(serializable, *aOptionalValue,
|
2019-01-28 12:48:35 +03:00
|
|
|
aDelayedStart, aManager);
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
2017-03-14 14:29:43 +03:00
|
|
|
if (aValue) {
|
2017-04-24 13:09:39 +03:00
|
|
|
return SerializeInputStream(aStream, *aValue, aManager, aDelayedStart);
|
2017-03-14 14:29:43 +03:00
|
|
|
}
|
|
|
|
|
2017-04-24 13:09:39 +03:00
|
|
|
return SerializeInputStream(aStream, *aOptionalValue, aManager,
|
|
|
|
aDelayedStart);
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
2019-01-28 12:49:13 +03:00
|
|
|
void ActivateAndCleanupIPCStream(IPCStream& aValue, bool aConsumedByIPC,
|
|
|
|
bool aDelayedStart) {
|
|
|
|
// Cleanup file descriptors if necessary
|
|
|
|
if (aValue.optionalFds().type() ==
|
|
|
|
OptionalFileDescriptorSet::TPFileDescriptorSetChild) {
|
|
|
|
AutoTArray<FileDescriptor, 4> fds;
|
2016-05-15 20:32:09 +03:00
|
|
|
|
2019-01-28 12:49:13 +03:00
|
|
|
auto fdSetActor = static_cast<FileDescriptorSetChild*>(
|
|
|
|
aValue.optionalFds().get_PFileDescriptorSetChild());
|
|
|
|
MOZ_ASSERT(fdSetActor);
|
2016-05-15 20:32:09 +03:00
|
|
|
|
2019-01-28 12:49:13 +03:00
|
|
|
// FileDescriptorSet doesn't clear its fds in its ActorDestroy, so we
|
|
|
|
// unconditionally forget them here. The fds themselves are auto-closed
|
|
|
|
// in ~FileDescriptor since they originated in this process.
|
|
|
|
fdSetActor->ForgetFileDescriptors(fds);
|
2016-10-14 09:27:28 +03:00
|
|
|
|
2019-01-28 12:49:13 +03:00
|
|
|
if (!aConsumedByIPC) {
|
|
|
|
Unused << FileDescriptorSetChild::Send__delete__(fdSetActor);
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
2019-01-28 12:49:13 +03:00
|
|
|
} else if (aValue.optionalFds().type() ==
|
|
|
|
OptionalFileDescriptorSet::TPFileDescriptorSetParent) {
|
|
|
|
AutoTArray<FileDescriptor, 4> fds;
|
2016-05-15 20:32:09 +03:00
|
|
|
|
2019-01-28 12:49:13 +03:00
|
|
|
auto fdSetActor = static_cast<FileDescriptorSetParent*>(
|
|
|
|
aValue.optionalFds().get_PFileDescriptorSetParent());
|
|
|
|
MOZ_ASSERT(fdSetActor);
|
2016-05-15 20:32:09 +03:00
|
|
|
|
2019-01-28 12:49:13 +03:00
|
|
|
// FileDescriptorSet doesn't clear its fds in its ActorDestroy, so we
|
|
|
|
// unconditionally forget them here. The fds themselves are auto-closed
|
|
|
|
// in ~FileDescriptor since they originated in this process.
|
|
|
|
fdSetActor->ForgetFileDescriptors(fds);
|
2016-05-15 20:32:09 +03:00
|
|
|
|
2019-01-28 12:49:13 +03:00
|
|
|
if (!aConsumedByIPC) {
|
|
|
|
Unused << FileDescriptorSetParent::Send__delete__(fdSetActor);
|
|
|
|
}
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
2019-01-28 12:49:13 +03:00
|
|
|
// Activate IPCRemoteStreamParams.
|
|
|
|
InputStreamHelper::PostSerializationActivation(aValue.stream(),
|
|
|
|
aConsumedByIPC, aDelayedStart);
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
2019-01-28 12:49:13 +03:00
|
|
|
void ActivateAndCleanupIPCStream(OptionalIPCStream& aValue, bool aConsumedByIPC,
|
|
|
|
bool aDelayedStart) {
|
2016-05-15 20:32:09 +03:00
|
|
|
if (aValue.type() == OptionalIPCStream::Tvoid_t) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-01-28 12:49:13 +03:00
|
|
|
ActivateAndCleanupIPCStream(aValue.get_IPCStream(), aConsumedByIPC,
|
|
|
|
aDelayedStart);
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
2017-03-14 14:29:43 +03:00
|
|
|
// Returns false if the serialization should not proceed. This means that the
|
|
|
|
// inputStream is null.
|
|
|
|
bool NormalizeOptionalValue(nsIInputStream* aStream, IPCStream* aValue,
|
|
|
|
OptionalIPCStream* aOptionalValue) {
|
|
|
|
if (aValue) {
|
|
|
|
// if aStream is null, we will crash when serializing.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!aStream) {
|
|
|
|
*aOptionalValue = void_t();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
*aOptionalValue = IPCStream();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-05-15 20:32:09 +03:00
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
already_AddRefed<nsIInputStream> DeserializeIPCStream(const IPCStream& aValue) {
|
2017-03-14 14:28:58 +03:00
|
|
|
// Note, we explicitly do not support deserializing the PChildToParentStream
|
2017-03-14 14:29:43 +03:00
|
|
|
// actor on the child side nor the PParentToChildStream actor on the parent
|
|
|
|
// side.
|
2016-05-15 20:32:09 +03:00
|
|
|
|
|
|
|
AutoTArray<FileDescriptor, 4> fds;
|
2019-01-28 12:49:13 +03:00
|
|
|
if (aValue.optionalFds().type() ==
|
2016-05-15 20:32:09 +03:00
|
|
|
OptionalFileDescriptorSet::TPFileDescriptorSetParent) {
|
|
|
|
auto fdSetActor = static_cast<FileDescriptorSetParent*>(
|
2019-01-28 12:49:13 +03:00
|
|
|
aValue.optionalFds().get_PFileDescriptorSetParent());
|
2016-05-15 20:32:09 +03:00
|
|
|
MOZ_ASSERT(fdSetActor);
|
|
|
|
|
|
|
|
fdSetActor->ForgetFileDescriptors(fds);
|
|
|
|
MOZ_ASSERT(!fds.IsEmpty());
|
|
|
|
|
2018-03-16 16:29:15 +03:00
|
|
|
if (!FileDescriptorSetParent::Send__delete__(fdSetActor)) {
|
2016-05-15 20:32:09 +03:00
|
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
|
|
NS_WARNING("Failed to delete fd set actor.");
|
|
|
|
}
|
2019-01-28 12:49:13 +03:00
|
|
|
} else if (aValue.optionalFds().type() ==
|
2016-05-15 20:32:09 +03:00
|
|
|
OptionalFileDescriptorSet::TPFileDescriptorSetChild) {
|
|
|
|
auto fdSetActor = static_cast<FileDescriptorSetChild*>(
|
2019-01-28 12:49:13 +03:00
|
|
|
aValue.optionalFds().get_PFileDescriptorSetChild());
|
2016-05-15 20:32:09 +03:00
|
|
|
MOZ_ASSERT(fdSetActor);
|
|
|
|
|
|
|
|
fdSetActor->ForgetFileDescriptors(fds);
|
|
|
|
MOZ_ASSERT(!fds.IsEmpty());
|
|
|
|
|
2018-03-16 16:29:15 +03:00
|
|
|
Unused << FileDescriptorSetChild::Send__delete__(fdSetActor);
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
2019-01-28 12:49:13 +03:00
|
|
|
return InputStreamHelper::DeserializeInputStream(aValue.stream(), fds);
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
already_AddRefed<nsIInputStream> DeserializeIPCStream(
|
|
|
|
const OptionalIPCStream& aValue) {
|
|
|
|
if (aValue.type() == OptionalIPCStream::Tvoid_t) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return DeserializeIPCStream(aValue.get_IPCStream());
|
|
|
|
}
|
|
|
|
|
2017-04-24 13:09:39 +03:00
|
|
|
AutoIPCStream::AutoIPCStream(bool aDelayedStart)
|
2016-05-15 20:32:09 +03:00
|
|
|
: mInlineValue(void_t()),
|
|
|
|
mValue(nullptr),
|
|
|
|
mOptionalValue(&mInlineValue),
|
|
|
|
mTaken(false),
|
2017-04-24 13:09:39 +03:00
|
|
|
mDelayedStart(aDelayedStart) {}
|
2016-05-15 20:32:09 +03:00
|
|
|
|
2017-04-24 13:09:39 +03:00
|
|
|
AutoIPCStream::AutoIPCStream(IPCStream& aTarget, bool aDelayedStart)
|
2016-05-15 20:32:09 +03:00
|
|
|
: mInlineValue(void_t()),
|
|
|
|
mValue(&aTarget),
|
|
|
|
mOptionalValue(nullptr),
|
|
|
|
mTaken(false),
|
2017-04-24 13:09:39 +03:00
|
|
|
mDelayedStart(aDelayedStart) {}
|
2016-05-15 20:32:09 +03:00
|
|
|
|
2017-04-24 13:09:39 +03:00
|
|
|
AutoIPCStream::AutoIPCStream(OptionalIPCStream& aTarget, bool aDelayedStart)
|
2016-05-15 20:32:09 +03:00
|
|
|
: mInlineValue(void_t()),
|
|
|
|
mValue(nullptr),
|
|
|
|
mOptionalValue(&aTarget),
|
|
|
|
mTaken(false),
|
2017-04-24 13:09:39 +03:00
|
|
|
mDelayedStart(aDelayedStart) {
|
2016-05-15 20:32:09 +03:00
|
|
|
*mOptionalValue = void_t();
|
|
|
|
}
|
|
|
|
|
|
|
|
AutoIPCStream::~AutoIPCStream() {
|
|
|
|
MOZ_ASSERT(mValue || mOptionalValue);
|
|
|
|
if (mValue && IsSet()) {
|
2019-01-28 12:49:13 +03:00
|
|
|
ActivateAndCleanupIPCStream(*mValue, mTaken, mDelayedStart);
|
2016-05-15 20:32:09 +03:00
|
|
|
} else {
|
2019-01-28 12:49:13 +03:00
|
|
|
ActivateAndCleanupIPCStream(*mOptionalValue, mTaken, mDelayedStart);
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-21 13:27:26 +03:00
|
|
|
bool AutoIPCStream::Serialize(nsIInputStream* aStream,
|
|
|
|
dom::nsIContentChild* aManager) {
|
2017-03-09 16:11:21 +03:00
|
|
|
MOZ_ASSERT(aStream || !mValue);
|
2016-05-15 20:32:09 +03:00
|
|
|
MOZ_ASSERT(aManager);
|
|
|
|
MOZ_ASSERT(mValue || mOptionalValue);
|
|
|
|
MOZ_ASSERT(!mTaken);
|
|
|
|
MOZ_ASSERT(!IsSet());
|
|
|
|
|
2017-03-14 14:29:43 +03:00
|
|
|
// If NormalizeOptionalValue returns false, we don't have to proceed.
|
|
|
|
if (!NormalizeOptionalValue(aStream, mValue, mOptionalValue)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-04-24 13:09:39 +03:00
|
|
|
if (!SerializeInputStreamChild(aStream, aManager, mValue, mOptionalValue,
|
|
|
|
mDelayedStart)) {
|
2017-03-14 14:29:43 +03:00
|
|
|
MOZ_CRASH("IPCStream creation failed!");
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool AutoIPCStream::Serialize(nsIInputStream* aStream,
|
|
|
|
PBackgroundChild* aManager) {
|
2017-03-09 16:11:21 +03:00
|
|
|
MOZ_ASSERT(aStream || !mValue);
|
2016-05-15 20:32:09 +03:00
|
|
|
MOZ_ASSERT(aManager);
|
|
|
|
MOZ_ASSERT(mValue || mOptionalValue);
|
|
|
|
MOZ_ASSERT(!mTaken);
|
|
|
|
MOZ_ASSERT(!IsSet());
|
|
|
|
|
2017-03-14 14:29:43 +03:00
|
|
|
// If NormalizeOptionalValue returns false, we don't have to proceed.
|
|
|
|
if (!NormalizeOptionalValue(aStream, mValue, mOptionalValue)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-04-24 13:09:39 +03:00
|
|
|
if (!SerializeInputStreamChild(aStream, aManager, mValue, mOptionalValue,
|
|
|
|
mDelayedStart)) {
|
2017-03-14 14:29:43 +03:00
|
|
|
MOZ_CRASH("IPCStream creation failed!");
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
2017-03-14 14:29:43 +03:00
|
|
|
bool AutoIPCStream::Serialize(nsIInputStream* aStream,
|
|
|
|
dom::nsIContentParent* aManager) {
|
2017-03-09 16:11:21 +03:00
|
|
|
MOZ_ASSERT(aStream || !mValue);
|
2016-05-15 20:32:09 +03:00
|
|
|
MOZ_ASSERT(aManager);
|
|
|
|
MOZ_ASSERT(mValue || mOptionalValue);
|
|
|
|
MOZ_ASSERT(!mTaken);
|
|
|
|
MOZ_ASSERT(!IsSet());
|
|
|
|
|
2017-03-14 14:29:43 +03:00
|
|
|
// If NormalizeOptionalValue returns false, we don't have to proceed.
|
|
|
|
if (!NormalizeOptionalValue(aStream, mValue, mOptionalValue)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-04-24 13:09:39 +03:00
|
|
|
if (!SerializeInputStreamParent(aStream, aManager, mValue, mOptionalValue,
|
|
|
|
mDelayedStart)) {
|
2017-03-14 14:29:43 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool AutoIPCStream::Serialize(nsIInputStream* aStream,
|
|
|
|
PBackgroundParent* aManager) {
|
2017-03-09 16:11:21 +03:00
|
|
|
MOZ_ASSERT(aStream || !mValue);
|
2016-05-15 20:32:09 +03:00
|
|
|
MOZ_ASSERT(aManager);
|
|
|
|
MOZ_ASSERT(mValue || mOptionalValue);
|
|
|
|
MOZ_ASSERT(!mTaken);
|
|
|
|
MOZ_ASSERT(!IsSet());
|
|
|
|
|
2017-03-14 14:29:43 +03:00
|
|
|
// If NormalizeOptionalValue returns false, we don't have to proceed.
|
|
|
|
if (!NormalizeOptionalValue(aStream, mValue, mOptionalValue)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-04-24 13:09:39 +03:00
|
|
|
if (!SerializeInputStreamParent(aStream, aManager, mValue, mOptionalValue,
|
|
|
|
mDelayedStart)) {
|
2017-03-14 14:29:43 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool AutoIPCStream::IsSet() const {
|
|
|
|
MOZ_ASSERT(mValue || mOptionalValue);
|
|
|
|
if (mValue) {
|
2019-01-28 12:49:13 +03:00
|
|
|
return mValue->stream().type() != InputStreamParams::T__None;
|
2016-05-15 20:32:09 +03:00
|
|
|
} else {
|
|
|
|
return mOptionalValue->type() != OptionalIPCStream::Tvoid_t &&
|
2019-01-28 12:49:13 +03:00
|
|
|
mOptionalValue->get_IPCStream().stream().type() !=
|
|
|
|
InputStreamParams::T__None;
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IPCStream& AutoIPCStream::TakeValue() {
|
|
|
|
MOZ_ASSERT(mValue || mOptionalValue);
|
|
|
|
MOZ_ASSERT(!mTaken);
|
|
|
|
MOZ_ASSERT(IsSet());
|
|
|
|
|
|
|
|
mTaken = true;
|
|
|
|
|
|
|
|
if (mValue) {
|
|
|
|
return *mValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
IPCStream& value = mOptionalValue->get_IPCStream();
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
OptionalIPCStream& AutoIPCStream::TakeOptionalValue() {
|
|
|
|
MOZ_ASSERT(!mTaken);
|
|
|
|
MOZ_ASSERT(!mValue);
|
|
|
|
MOZ_ASSERT(mOptionalValue);
|
|
|
|
mTaken = true;
|
|
|
|
return *mOptionalValue;
|
|
|
|
}
|
|
|
|
|
Bug 1443954 - Part 3: Add support for RefCounted types to IPDL, r=bz,froydnj,baku
This patch was reviewed in parts, however the intermediate states would not build:
Bug 1443954 - Part 3A: Strip pointers from the argument to WriteParam and WriteIPDLParam before selecting the ParamTraits impl, r=froydnj
Bug 1443954 - Part 3B: Move nsIAlertNotification serialization to the refcounted system, r=bz
Bug 1443954 - Part 3C: Move geolocation serialization to the refcounted system, r=bz
Bug 1443954 - Part 3D: Move nsIInputStream serialization to the refcounted system, r=baku
Bug 1443954 - Part 3E: Move BlobImpl serialization to the refcounted system, r=baku
Bug 1443954 - Part 3F: Correctly implement ParamTraits for actors after the ParamTraits changes, r=froydnj
2018-03-07 04:14:59 +03:00
|
|
|
void IPDLParamTraits<nsIInputStream>::Write(IPC::Message* aMsg,
|
|
|
|
IProtocol* aActor,
|
|
|
|
nsIInputStream* aParam) {
|
2018-02-23 23:26:38 +03:00
|
|
|
mozilla::ipc::AutoIPCStream autoStream;
|
|
|
|
bool ok = false;
|
|
|
|
bool found = false;
|
|
|
|
|
|
|
|
// We can only serialize our nsIInputStream if it's going to be sent over one
|
|
|
|
// of the protocols we support, or a protocol which is managed by one of the
|
|
|
|
// protocols we support.
|
|
|
|
IProtocol* actor = aActor;
|
|
|
|
while (!found && actor) {
|
|
|
|
switch (actor->GetProtocolTypeId()) {
|
|
|
|
case PContentMsgStart:
|
|
|
|
if (actor->GetSide() == mozilla::ipc::ParentSide) {
|
|
|
|
ok = autoStream.Serialize(
|
|
|
|
aParam, static_cast<mozilla::dom::ContentParent*>(actor));
|
|
|
|
} else {
|
|
|
|
MOZ_RELEASE_ASSERT(actor->GetSide() == mozilla::ipc::ChildSide);
|
|
|
|
ok = autoStream.Serialize(
|
|
|
|
aParam, static_cast<mozilla::dom::ContentChild*>(actor));
|
|
|
|
}
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
case PBackgroundMsgStart:
|
|
|
|
if (actor->GetSide() == mozilla::ipc::ParentSide) {
|
|
|
|
ok = autoStream.Serialize(
|
|
|
|
aParam, static_cast<mozilla::ipc::PBackgroundParent*>(actor));
|
|
|
|
} else {
|
|
|
|
MOZ_RELEASE_ASSERT(actor->GetSide() == mozilla::ipc::ChildSide);
|
|
|
|
ok = autoStream.Serialize(
|
|
|
|
aParam, static_cast<mozilla::ipc::PBackgroundChild*>(actor));
|
|
|
|
}
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try the actor's manager.
|
|
|
|
actor = actor->Manager();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!found) {
|
|
|
|
aActor->FatalError(
|
|
|
|
"Attempt to send nsIInputStream over an unsupported ipdl protocol");
|
|
|
|
}
|
|
|
|
MOZ_RELEASE_ASSERT(ok, "Failed to serialize nsIInputStream");
|
|
|
|
|
|
|
|
WriteIPDLParam(aMsg, aActor, autoStream.TakeOptionalValue());
|
|
|
|
}
|
|
|
|
|
Bug 1443954 - Part 3: Add support for RefCounted types to IPDL, r=bz,froydnj,baku
This patch was reviewed in parts, however the intermediate states would not build:
Bug 1443954 - Part 3A: Strip pointers from the argument to WriteParam and WriteIPDLParam before selecting the ParamTraits impl, r=froydnj
Bug 1443954 - Part 3B: Move nsIAlertNotification serialization to the refcounted system, r=bz
Bug 1443954 - Part 3C: Move geolocation serialization to the refcounted system, r=bz
Bug 1443954 - Part 3D: Move nsIInputStream serialization to the refcounted system, r=baku
Bug 1443954 - Part 3E: Move BlobImpl serialization to the refcounted system, r=baku
Bug 1443954 - Part 3F: Correctly implement ParamTraits for actors after the ParamTraits changes, r=froydnj
2018-03-07 04:14:59 +03:00
|
|
|
bool IPDLParamTraits<nsIInputStream>::Read(const IPC::Message* aMsg,
|
|
|
|
PickleIterator* aIter,
|
|
|
|
IProtocol* aActor,
|
|
|
|
RefPtr<nsIInputStream>* aResult) {
|
2018-02-23 23:26:38 +03:00
|
|
|
mozilla::ipc::OptionalIPCStream ipcStream;
|
|
|
|
if (!ReadIPDLParam(aMsg, aIter, aActor, &ipcStream)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
*aResult = mozilla::ipc::DeserializeIPCStream(ipcStream);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-05-15 20:32:09 +03:00
|
|
|
} // namespace ipc
|
|
|
|
} // namespace mozilla
|