File: StructuredCloneData.cpp

package info (click to toggle)
firefox 149.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,767,760 kB
  • sloc: cpp: 7,416,064; javascript: 6,752,859; ansic: 3,774,850; python: 1,250,473; xml: 641,578; asm: 439,191; java: 186,617; sh: 56,634; makefile: 18,856; objc: 13,092; perl: 12,763; pascal: 5,960; yacc: 4,583; cs: 3,846; lex: 1,720; ruby: 1,002; php: 436; lisp: 258; awk: 105; sql: 66; sed: 53; csh: 10; exp: 6
file content (132 lines) | stat: -rw-r--r-- 4,461 bytes parent folder | download
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, &notNull)) {
    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;
}