tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SerializedStructuredCloneBuffer.cpp (3123B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "mozilla/ipc/SerializedStructuredCloneBuffer.h"
      8 #include "js/StructuredClone.h"
      9 
     10 namespace IPC {
     11 
     12 void ParamTraits<JSStructuredCloneData>::Write(MessageWriter* aWriter,
     13                                               const paramType& aParam) {
     14  MOZ_ASSERT(!(aParam.Size() % sizeof(uint64_t)));
     15 
     16  // We can only construct shared memory regions up to 4Gb in size, making that
     17  // the maximum possible JSStructuredCloneData size.
     18  mozilla::CheckedUint32 size = aParam.Size();
     19  if (!size.isValid()) {
     20    aWriter->FatalError("JSStructuredCloneData over 4Gb in size");
     21    return;
     22  }
     23  WriteParam(aWriter, size.value());
     24 
     25  MessageBufferWriter bufWriter(aWriter, size.value());
     26  aParam.ForEachDataChunk([&](const char* aData, size_t aSize) {
     27    return bufWriter.WriteBytes(aData, aSize);
     28  });
     29 }
     30 
     31 bool ParamTraits<JSStructuredCloneData>::Read(MessageReader* aReader,
     32                                              paramType* aResult) {
     33  uint32_t length = 0;
     34  if (!ReadParam(aReader, &length)) {
     35    aReader->FatalError("JSStructuredCloneData length read failed");
     36    return false;
     37  }
     38  MOZ_ASSERT(!(length % sizeof(uint64_t)));
     39 
     40  // Borrowing is not suitable to use for IPC to hand out data because we often
     41  // want to store the data somewhere for processing after IPC has released the
     42  // underlying buffers.
     43  //
     44  // This deserializer previously used a mechanism to transfer ownership over
     45  // the underlying buffers from IPC into the JSStructuredCloneData. This was
     46  // removed when support for serializing over shared memory was added, as the
     47  // benefit for avoiding copies was limited due to it only functioning for
     48  // buffers under 64k in size (as larger buffers would be serialized using
     49  // shared memory), and it added substantial complexity to the BufferList type
     50  // and the IPC serialization layer due to things like buffer alignment. This
     51  // can be revisited in the future if it turns out to be a noticable
     52  // performance regression. (bug 1783242)
     53 
     54  mozilla::BufferList<js::SystemAllocPolicy> buffers(0, 0, 4096);
     55  MessageBufferReader bufReader(aReader, length);
     56  uint32_t read = 0;
     57  while (read < length) {
     58    size_t bufLen;
     59    char* buf = buffers.AllocateBytes(length - read, &bufLen);
     60    if (!buf) {
     61      // Would be nice to allow actor to control behaviour here (bug 1784307)
     62      NS_ABORT_OOM(length - read);
     63      return false;
     64    }
     65    if (!bufReader.ReadBytesInto(buf, bufLen)) {
     66      aReader->FatalError("JSStructuredCloneData ReadBytesInto failed");
     67      return false;
     68    }
     69    read += bufLen;
     70  }
     71 
     72  MOZ_ASSERT(read == length);
     73  *aResult = JSStructuredCloneData(
     74      std::move(buffers), JS::StructuredCloneScope::DifferentProcess,
     75      OwnTransferablePolicy::IgnoreTransferablesIfAny);
     76  return true;
     77 }
     78 
     79 }  // namespace IPC