bool StructuredCloneIPCHelper::Copy(const StructuredCloneIPCHelper& aHelper) { if (!aHelper.mData) { return true; } uint64_t* data = static_cast<uint64_t*>(malloc(aHelper.mDataLength)); if (!data) { return false; } memcpy(data, aHelper.mData, aHelper.mDataLength); mData = data; mDataLength = aHelper.mDataLength; mDataOwned = eAllocated; MOZ_ASSERT(BlobImpls().IsEmpty()); BlobImpls().AppendElements(aHelper.BlobImpls()); MOZ_ASSERT(GetImages().IsEmpty()); return true; }
bool StructuredCloneData::Copy(const StructuredCloneData& aData) { if (!aData.mData) { return true; } uint64_t* data = static_cast<uint64_t*>(js_malloc(aData.mDataLength)); if (!data) { return false; } memcpy(data, aData.mData, aData.mDataLength); mData = data; mDataLength = aData.mDataLength; mDataOwned = eJSAllocated; MOZ_ASSERT(BlobImpls().IsEmpty()); BlobImpls().AppendElements(aData.BlobImpls()); MOZ_ASSERT(GetImages().IsEmpty()); return true; }
bool StructuredCloneData::Copy(const StructuredCloneData& aData) { if (!aData.Data()) { return true; } if (aData.SharedData()) { mSharedData = aData.SharedData(); } else { mSharedData = SharedJSAllocatedData::CreateFromExternalData(aData.Data(), aData.DataLength()); NS_ENSURE_TRUE(mSharedData, false); } PortIdentifiers().AppendElements(aData.PortIdentifiers()); MOZ_ASSERT(BlobImpls().IsEmpty()); BlobImpls().AppendElements(aData.BlobImpls()); MOZ_ASSERT(GetSurfaces().IsEmpty()); return true; }
void SharedMessagePortMessage::Write(JSContext* aCx, JS::Handle<JS::Value> aValue, JS::Handle<JS::Value> aTransfer, ErrorResult& aRv) { StructuredCloneHelper::Write(aCx, aValue, aTransfer, aRv); if (NS_WARN_IF(aRv.Failed())) { return; } const nsTArray<nsRefPtr<BlobImpl>>& blobImpls = BlobImpls(); for (uint32_t i = 0, len = blobImpls.Length(); i < len; ++i) { if (!blobImpls[i]->MayBeClonedToOtherThreads()) { aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR); return; } } FallibleTArray<uint8_t> cloneData; MoveBufferDataToArray(cloneData, aRv); if (NS_WARN_IF(aRv.Failed())) { return; } MOZ_ASSERT(mData.IsEmpty()); mData.SwapElements(cloneData); }
bool StructuredCloneBlob::Holder::WriteStructuredClone( JSContext* aCx, JSStructuredCloneWriter* aWriter, StructuredCloneHolder* aHolder) { auto& data = mBuffer->data(); if (!JS_WriteUint32Pair(aWriter, SCTAG_DOM_STRUCTURED_CLONE_HOLDER, 0) || !JS_WriteUint32Pair(aWriter, data.Size(), JS_STRUCTURED_CLONE_VERSION) || !JS_WriteUint32Pair(aWriter, aHolder->BlobImpls().Length(), BlobImpls().Length())) { return false; } aHolder->BlobImpls().AppendElements(BlobImpls()); return data.ForEachDataChunk([&](const char* aData, size_t aSize) { return JS_WriteBytes(aWriter, aData, aSize); }); }
bool StructuredCloneBlob::Holder::ReadStructuredCloneInternal( JSContext* aCx, JSStructuredCloneReader* aReader, StructuredCloneHolder* aHolder) { uint32_t length; uint32_t version; if (!JS_ReadUint32Pair(aReader, &length, &version)) { return false; } uint32_t blobOffset; uint32_t blobCount; if (!JS_ReadUint32Pair(aReader, &blobOffset, &blobCount)) { return false; } if (blobCount) { #ifdef FUZZING if (blobOffset >= aHolder->BlobImpls().Length()) { return false; } #endif BlobImpls().AppendElements(&aHolder->BlobImpls()[blobOffset], blobCount); } JSStructuredCloneData data(mStructuredCloneScope); while (length) { size_t size; char* buffer = data.AllocateBytes(length, &size); if (!buffer || !JS_ReadBytes(aReader, buffer, size)) { return false; } length -= size; } mBuffer = MakeUnique<JSAutoStructuredCloneBuffer>( mStructuredCloneScope, &StructuredCloneHolder::sCallbacks, this); mBuffer->adopt(std::move(data), version, &StructuredCloneHolder::sCallbacks); return true; }