1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "StructuredCloneData.h"
#include "ipc/IPCMessageUtilsSpecializations.h"
#include "mozilla/dom/BlobImpl.h"
#include "mozilla/dom/DOMTypes.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/ipc/SerializedStructuredCloneBuffer.h"
#include "nsContentUtils.h"
using namespace mozilla::ipc;
namespace mozilla::dom::ipc {
StructuredCloneData::StructuredCloneData()
: StructuredCloneData(StructuredCloneScope::DifferentProcess,
StructuredCloneHolder::TransferringSupported) {}
StructuredCloneData::StructuredCloneData(
StructuredCloneScope aScope, TransferringSupport aSupportsTransferring)
: StructuredCloneHolder(StructuredCloneHolder::CloningSupported,
aSupportsTransferring, aScope) {
MOZ_ASSERT(aScope == StructuredCloneScope::DifferentProcess ||
aScope == StructuredCloneScope::UnknownDestination);
}
StructuredCloneData::~StructuredCloneData() = default;
void StructuredCloneData::WriteIPCParams(IPC::MessageWriter* aWriter) {
MOZ_RELEASE_ASSERT(
CloneScope() == StructuredCloneScope::DifferentProcess,
"Cannot serialize same-process StructuredCloneData over IPC");
AssertAttachmentsMatchFlags();
WriteParam(aWriter, BufferVersion());
WriteParam(aWriter, BufferData());
// Write all cloneable attachments directly to IPC.
std::apply([&](auto&... member) { WriteParams(aWriter, member...); },
CloneableAttachmentArrays());
// Also write all transferable members, if we support transferring.
if (SupportsTransferring()) {
std::apply([&](auto&... member) { WriteParams(aWriter, member...); },
TransferableAttachmentArrays());
}
}
bool StructuredCloneData::ReadIPCParams(IPC::MessageReader* aReader) {
MOZ_ASSERT(!mBuffer, "StructuredCloneData was previously initialized");
GeckoChildID originChildID =
aReader->GetActor()
? aReader->GetActor()->ToplevelProtocol()->OtherChildIDMaybeInvalid()
: kInvalidGeckoChildID;
uint32_t version;
JSStructuredCloneData data(JS::StructuredCloneScope::DifferentProcess);
if (!ReadParam(aReader, &version) || !ReadParam(aReader, &data)) {
return false;
}
Adopt(std::move(data), version, originChildID);
if (!std::apply(
[&](auto&... member) { return ReadParams(aReader, member...); },
CloneableAttachmentArrays())) {
return false;
}
if (SupportsTransferring()) {
if (!std::apply(
[&](auto&... member) { return ReadParams(aReader, member...); },
TransferableAttachmentArrays())) {
return false;
}
}
AssertAttachmentsMatchFlags();
return true;
}
bool StructuredCloneData::CopyExternalData(const char* aData,
size_t aDataLength,
uint32_t aVersion) {
MOZ_ASSERT(!mBuffer, "StructuredCloneData was previously initialized");
JSStructuredCloneData data(JS::StructuredCloneScope::DifferentProcess);
if (!data.AppendBytes(aData, aDataLength)) {
return false;
}
Adopt(std::move(data), aVersion);
return true;
}
} // namespace mozilla::dom::ipc
void IPC::ParamTraits<mozilla::dom::ipc::StructuredCloneData*>::Write(
MessageWriter* aWriter, paramType* aParam) {
WriteParam(aWriter, aParam != nullptr);
if (aParam) {
WriteParam(aWriter, aParam->SupportsTransferring());
aParam->WriteIPCParams(aWriter);
}
}
bool IPC::ParamTraits<mozilla::dom::ipc::StructuredCloneData*>::Read(
MessageReader* aReader, RefPtr<paramType>* aResult) {
bool notNull = false;
if (!ReadParam(aReader, ¬Null)) {
return false;
}
if (notNull) {
bool supportsTransferring;
if (!ReadParam(aReader, &supportsTransferring)) {
return false;
}
*aResult = mozilla::MakeRefPtr<paramType>(
JS::StructuredCloneScope::DifferentProcess,
supportsTransferring
? mozilla::dom::StructuredCloneHolder::TransferringSupported
: mozilla::dom::StructuredCloneHolder::TransferringNotSupported);
return (*aResult)->ReadIPCParams(aReader);
}
return true;
}
|