mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1184995 - StructuredCloneHelper for BroadcastChannel and DataStore, r=smaug
This commit is contained in:
parent
74ad9a8c6b
commit
d5fb31ae84
@ -21,30 +21,6 @@ NS_INTERFACE_MAP_END
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(FileList)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(FileList)
|
||||
|
||||
/* static */ already_AddRefed<FileList>
|
||||
FileList::Create(nsISupports* aParent, FileListClonedData* aData)
|
||||
{
|
||||
MOZ_ASSERT(aData);
|
||||
|
||||
nsRefPtr<FileList> fileList = new FileList(aParent);
|
||||
|
||||
const nsTArray<nsRefPtr<BlobImpl>>& blobImpls = aData->BlobImpls();
|
||||
for (uint32_t i = 0; i < blobImpls.Length(); ++i) {
|
||||
const nsRefPtr<BlobImpl>& blobImpl = blobImpls[i];
|
||||
MOZ_ASSERT(blobImpl);
|
||||
MOZ_ASSERT(blobImpl->IsFile());
|
||||
|
||||
nsRefPtr<File> file = File::Create(aParent, blobImpl);
|
||||
MOZ_ASSERT(file);
|
||||
|
||||
if (NS_WARN_IF(!fileList->Append(file))) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return fileList.forget();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
FileList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
@ -67,19 +43,5 @@ FileList::Item(uint32_t aIndex, nsISupports** aFile)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<FileListClonedData>
|
||||
FileList::CreateClonedData() const
|
||||
{
|
||||
nsTArray<nsRefPtr<BlobImpl>> blobImpls;
|
||||
for (uint32_t i = 0; i < mFiles.Length(); ++i) {
|
||||
blobImpls.AppendElement(mFiles[i]->Impl());
|
||||
}
|
||||
|
||||
nsRefPtr<FileListClonedData> data = new FileListClonedData(blobImpls);
|
||||
return data.forget();
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS0(FileListClonedData)
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -7,6 +7,8 @@
|
||||
#ifndef mozilla_dom_FileList_h
|
||||
#define mozilla_dom_FileList_h
|
||||
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIDOMFileList.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
@ -16,27 +18,6 @@ namespace dom {
|
||||
class BlobImpls;
|
||||
class File;
|
||||
|
||||
class FileListClonedData final : public nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
explicit FileListClonedData(const nsTArray<nsRefPtr<BlobImpl>>& aBlobImpls)
|
||||
: mBlobImpls(aBlobImpls)
|
||||
{}
|
||||
|
||||
const nsTArray<nsRefPtr<BlobImpl>>& BlobImpls() const
|
||||
{
|
||||
return mBlobImpls;
|
||||
}
|
||||
|
||||
private:
|
||||
~FileListClonedData()
|
||||
{}
|
||||
|
||||
const nsTArray<nsRefPtr<BlobImpl>> mBlobImpls;
|
||||
};
|
||||
|
||||
class FileList final : public nsIDOMFileList,
|
||||
public nsWrapperCache
|
||||
{
|
||||
@ -50,9 +31,6 @@ public:
|
||||
: mParent(aParent)
|
||||
{}
|
||||
|
||||
static already_AddRefed<FileList>
|
||||
Create(nsISupports* aParent, FileListClonedData* aData);
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
@ -114,9 +92,6 @@ public:
|
||||
return mFiles.Length();
|
||||
}
|
||||
|
||||
// Useful for cloning
|
||||
already_AddRefed<FileListClonedData> CreateClonedData() const;
|
||||
|
||||
private:
|
||||
~FileList() {}
|
||||
|
||||
|
@ -28,7 +28,8 @@ PostMessageEvent::PostMessageEvent(nsGlobalWindow* aSource,
|
||||
nsGlobalWindow* aTargetWindow,
|
||||
nsIPrincipal* aProvidedPrincipal,
|
||||
bool aTrustedCaller)
|
||||
: mSource(aSource),
|
||||
: StructuredCloneHelper(CloningSupported, TransferringSupported),
|
||||
mSource(aSource),
|
||||
mCallerOrigin(aCallerOrigin),
|
||||
mTargetWindow(aTargetWindow),
|
||||
mProvidedPrincipal(aProvidedPrincipal),
|
||||
|
@ -199,8 +199,10 @@ StructuredCloneHelperInternal::FreeTransferCallback(uint32_t aTag,
|
||||
|
||||
// StructuredCloneHelper class
|
||||
|
||||
StructuredCloneHelper::StructuredCloneHelper(uint32_t aFlags)
|
||||
: mFlags(aFlags)
|
||||
StructuredCloneHelper::StructuredCloneHelper(CloningSupport aSupportsCloning,
|
||||
TransferringSupport aSupportsTransferring)
|
||||
: mSupportsCloning(aSupportsCloning == CloningSupported)
|
||||
, mSupportsTransferring(aSupportsTransferring == TransferringSupported)
|
||||
, mParent(nullptr)
|
||||
{}
|
||||
|
||||
@ -209,6 +211,13 @@ StructuredCloneHelper::~StructuredCloneHelper()
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool
|
||||
StructuredCloneHelper::Write(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
return Write(aCx, aValue, JS::UndefinedHandleValue);
|
||||
}
|
||||
|
||||
bool
|
||||
StructuredCloneHelper::Write(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue,
|
||||
@ -227,7 +236,36 @@ StructuredCloneHelper::Read(nsISupports* aParent,
|
||||
mozilla::AutoRestore<nsISupports*> guard(mParent);
|
||||
mParent = aParent;
|
||||
|
||||
return StructuredCloneHelperInternal::Read(aCx, aValue);
|
||||
bool ok = StructuredCloneHelperInternal::Read(aCx, aValue);
|
||||
mBlobImplArray.Clear();
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool
|
||||
StructuredCloneHelper::ReadFromBuffer(nsISupports* aParent,
|
||||
JSContext* aCx,
|
||||
uint64_t* aBuffer,
|
||||
size_t aBufferLength,
|
||||
nsTArray<nsRefPtr<BlobImpl>>& aBlobImpls,
|
||||
JS::MutableHandle<JS::Value> aValue)
|
||||
{
|
||||
MOZ_ASSERT(!mBuffer, "ReadFromBuffer() must be called without a Write().");
|
||||
MOZ_ASSERT(mBlobImplArray.IsEmpty());
|
||||
|
||||
MOZ_ASSERT(aBuffer);
|
||||
MOZ_ASSERT_IF(!mSupportsCloning, aBlobImpls.IsEmpty());
|
||||
|
||||
mozilla::AutoRestore<nsISupports*> guard(mParent);
|
||||
mParent = aParent;
|
||||
|
||||
mBlobImplArray.AppendElements(aBlobImpls);
|
||||
|
||||
bool ok = JS_ReadStructuredClone(aCx, aBuffer, aBufferLength,
|
||||
JS_STRUCTURED_CLONE_VERSION, aValue,
|
||||
&gCallbacks, this);
|
||||
|
||||
mBlobImplArray.Clear();
|
||||
return ok;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
@ -236,54 +274,59 @@ StructuredCloneHelper::ReadCallback(JSContext* aCx,
|
||||
uint32_t aTag,
|
||||
uint32_t aIndex)
|
||||
{
|
||||
MOZ_ASSERT(mSupportsCloning);
|
||||
|
||||
if (aTag == SCTAG_DOM_BLOB) {
|
||||
MOZ_ASSERT(!(mFlags & eBlobNotSupported));
|
||||
MOZ_ASSERT(aIndex < mBlobImplArray.Length());
|
||||
nsRefPtr<BlobImpl> blobImpl = mBlobImplArray[aIndex];
|
||||
|
||||
BlobImpl* blobImpl;
|
||||
if (JS_ReadBytes(aReader, &blobImpl, sizeof(blobImpl))) {
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
// nsRefPtr<File> needs to go out of scope before toObjectOrNull() is
|
||||
// called because the static analysis thinks dereferencing XPCOM objects
|
||||
// can GC (because in some cases it can!), and a return statement with a
|
||||
// JSObject* type means that JSObject* is on the stack as a raw pointer
|
||||
// while destructors are running.
|
||||
JS::Rooted<JS::Value> val(aCx);
|
||||
{
|
||||
nsRefPtr<Blob> blob = Blob::Create(mParent, blobImpl);
|
||||
if (!ToJSValue(aCx, blob, &val)) {
|
||||
return nullptr;
|
||||
}
|
||||
// nsRefPtr<File> needs to go out of scope before toObjectOrNull() is
|
||||
// called because the static analysis thinks dereferencing XPCOM objects
|
||||
// can GC (because in some cases it can!), and a return statement with a
|
||||
// JSObject* type means that JSObject* is on the stack as a raw pointer
|
||||
// while destructors are running.
|
||||
JS::Rooted<JS::Value> val(aCx);
|
||||
{
|
||||
nsRefPtr<Blob> blob = Blob::Create(mParent, blobImpl);
|
||||
if (!ToJSValue(aCx, blob, &val)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &val.toObject();
|
||||
}
|
||||
|
||||
return &val.toObject();
|
||||
}
|
||||
|
||||
if (aTag == SCTAG_DOM_FILELIST) {
|
||||
MOZ_ASSERT(!(mFlags & eFileListNotSupported));
|
||||
JS::Rooted<JS::Value> val(aCx);
|
||||
{
|
||||
nsRefPtr<FileList> fileList = new FileList(mParent);
|
||||
|
||||
FileListClonedData* fileListClonedData;
|
||||
if (JS_ReadBytes(aReader, &fileListClonedData,
|
||||
sizeof(fileListClonedData))) {
|
||||
MOZ_ASSERT(fileListClonedData);
|
||||
// |aIndex| is the number of BlobImpls to use from |offset|.
|
||||
uint32_t tag, offset;
|
||||
if (!JS_ReadUint32Pair(aReader, &tag, &offset)) {
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(tag == 0);
|
||||
|
||||
// nsRefPtr<FileList> needs to go out of scope before toObjectOrNull() is
|
||||
// called because the static analysis thinks dereferencing XPCOM objects
|
||||
// can GC (because in some cases it can!), and a return statement with a
|
||||
// JSObject* type means that JSObject* is on the stack as a raw pointer
|
||||
// while destructors are running.
|
||||
JS::Rooted<JS::Value> val(aCx);
|
||||
{
|
||||
nsRefPtr<FileList> fileList =
|
||||
FileList::Create(mParent, fileListClonedData);
|
||||
if (!fileList || !ToJSValue(aCx, fileList, &val)) {
|
||||
for (uint32_t i = 0; i < aIndex; ++i) {
|
||||
uint32_t index = offset + i;
|
||||
MOZ_ASSERT(index < mBlobImplArray.Length());
|
||||
|
||||
nsRefPtr<BlobImpl> blobImpl = mBlobImplArray[index];
|
||||
MOZ_ASSERT(blobImpl->IsFile());
|
||||
|
||||
nsRefPtr<File> file = File::Create(mParent, blobImpl);
|
||||
if (!fileList->Append(file)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return &val.toObject();
|
||||
if (!ToJSValue(aCx, fileList, &val)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return &val.toObject();
|
||||
}
|
||||
|
||||
return NS_DOMReadStructuredClone(aCx, aReader, aTag, aIndex, nullptr);
|
||||
@ -294,27 +337,43 @@ StructuredCloneHelper::WriteCallback(JSContext* aCx,
|
||||
JSStructuredCloneWriter* aWriter,
|
||||
JS::Handle<JSObject*> aObj)
|
||||
{
|
||||
if (!mSupportsCloning) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// See if this is a File/Blob object.
|
||||
if (!(mFlags & eBlobNotSupported)) {
|
||||
{
|
||||
Blob* blob = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, aObj, blob))) {
|
||||
BlobImpl* blobImpl = blob->Impl();
|
||||
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_BLOB, 0) &&
|
||||
JS_WriteBytes(aWriter, &blobImpl, sizeof(blobImpl)) &&
|
||||
StoreISupports(blobImpl);
|
||||
if (JS_WriteUint32Pair(aWriter, SCTAG_DOM_BLOB,
|
||||
mBlobImplArray.Length())) {
|
||||
mBlobImplArray.AppendElement(blobImpl);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(mFlags & eFileListNotSupported)) {
|
||||
{
|
||||
FileList* fileList = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(FileList, aObj, fileList))) {
|
||||
nsRefPtr<FileListClonedData> fileListClonedData =
|
||||
fileList->CreateClonedData();
|
||||
MOZ_ASSERT(fileListClonedData);
|
||||
FileListClonedData* ptr = fileListClonedData.get();
|
||||
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_FILELIST, 0) &&
|
||||
JS_WriteBytes(aWriter, &ptr, sizeof(ptr)) &&
|
||||
StoreISupports(fileListClonedData);
|
||||
// A FileList is serialized writing the X number of elements and the offset
|
||||
// from mBlobImplArray. The Read will take X elements from mBlobImplArray
|
||||
// starting from the offset.
|
||||
if (!JS_WriteUint32Pair(aWriter, SCTAG_DOM_FILELIST,
|
||||
fileList->Length()) ||
|
||||
!JS_WriteUint32Pair(aWriter, 0,
|
||||
mBlobImplArray.Length())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < fileList->Length(); ++i) {
|
||||
mBlobImplArray.AppendElement(fileList->Item(i)->Impl());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,9 +388,9 @@ StructuredCloneHelper::ReadTransferCallback(JSContext* aCx,
|
||||
uint64_t aExtraData,
|
||||
JS::MutableHandleObject aReturnObject)
|
||||
{
|
||||
if (aTag == SCTAG_DOM_MAP_MESSAGEPORT) {
|
||||
MOZ_ASSERT(!(mFlags & eMessagePortNotSupported));
|
||||
MOZ_ASSERT(mSupportsTransferring);
|
||||
|
||||
if (aTag == SCTAG_DOM_MAP_MESSAGEPORT) {
|
||||
// This can be null.
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(mParent);
|
||||
|
||||
@ -370,7 +429,11 @@ StructuredCloneHelper::WriteTransferCallback(JSContext* aCx,
|
||||
void** aContent,
|
||||
uint64_t* aExtraData)
|
||||
{
|
||||
if (!(mFlags & eMessagePortNotSupported)) {
|
||||
if (!mSupportsTransferring) {
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
MessagePortBase* port = nullptr;
|
||||
nsresult rv = UNWRAP_OBJECT(MessagePort, aObj, port);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
@ -406,8 +469,9 @@ StructuredCloneHelper::FreeTransferCallback(uint32_t aTag,
|
||||
void* aContent,
|
||||
uint64_t aExtraData)
|
||||
{
|
||||
MOZ_ASSERT(mSupportsTransferring);
|
||||
|
||||
if (aTag == SCTAG_DOM_MAP_MESSAGEPORT) {
|
||||
MOZ_ASSERT(!(mFlags & eMessagePortNotSupported));
|
||||
MOZ_ASSERT(!aContent);
|
||||
MOZ_ASSERT(aExtraData < mPortIdentifiers.Length());
|
||||
MessagePort::ForceClose(mPortIdentifiers[aExtraData]);
|
||||
|
@ -76,6 +76,18 @@ public:
|
||||
bool Read(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aValue);
|
||||
|
||||
uint64_t* BufferData() const
|
||||
{
|
||||
MOZ_ASSERT(mBuffer, "Write() has never been called.");
|
||||
return mBuffer->data();
|
||||
}
|
||||
|
||||
size_t BufferSize() const
|
||||
{
|
||||
MOZ_ASSERT(mBuffer, "Write() has never been called.");
|
||||
return mBuffer->nbytes();
|
||||
}
|
||||
|
||||
protected:
|
||||
nsAutoPtr<JSAutoStructuredCloneBuffer> mBuffer;
|
||||
|
||||
@ -84,32 +96,36 @@ protected:
|
||||
#endif
|
||||
};
|
||||
|
||||
class BlobImpl;
|
||||
class MessagePortBase;
|
||||
class MessagePortIdentifier;
|
||||
|
||||
class StructuredCloneHelper : public StructuredCloneHelperInternal
|
||||
{
|
||||
public:
|
||||
enum StructuredCloneHelperFlags {
|
||||
eAll = 0,
|
||||
|
||||
// Disable the cloning of blobs. If a blob is part of the cloning value,
|
||||
// an exception will be thrown.
|
||||
eBlobNotSupported = 1 << 0,
|
||||
|
||||
// Disable the cloning of FileLists. If a FileList is part of the cloning
|
||||
// value, an exception will be thrown.
|
||||
eFileListNotSupported = 1 << 1,
|
||||
|
||||
// MessagePort can just be transfered. Using this flag we do not support
|
||||
// the transfering.
|
||||
eMessagePortNotSupported = 1 << 2,
|
||||
enum CloningSupport
|
||||
{
|
||||
CloningSupported,
|
||||
CloningNotSupported
|
||||
};
|
||||
|
||||
// aFlags is a bitmap of StructuredCloneHelperFlags.
|
||||
explicit StructuredCloneHelper(uint32_t aFlags = eAll);
|
||||
enum TransferringSupport
|
||||
{
|
||||
TransferringSupported,
|
||||
TransferringNotSupported
|
||||
};
|
||||
|
||||
// If cloning is supported, this object will clone objects such as Blobs,
|
||||
// FileList, ImageData, etc.
|
||||
// If transferring is supported, we will transfer MessagePorts and in the
|
||||
// future other transferrable objects.
|
||||
explicit StructuredCloneHelper(CloningSupport aSupportsCloning,
|
||||
TransferringSupport aSupportsTransferring);
|
||||
virtual ~StructuredCloneHelper();
|
||||
|
||||
bool Write(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue);
|
||||
|
||||
bool Write(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue,
|
||||
JS::Handle<JS::Value> aTransfer);
|
||||
@ -118,9 +134,22 @@ public:
|
||||
JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aValue);
|
||||
|
||||
bool ReadFromBuffer(nsISupports* aParent,
|
||||
JSContext* aCx,
|
||||
uint64_t* aBuffer,
|
||||
size_t aBufferLength,
|
||||
nsTArray<nsRefPtr<BlobImpl>>& aBlobImpls,
|
||||
JS::MutableHandle<JS::Value> aValue);
|
||||
|
||||
const nsTArray<nsRefPtr<BlobImpl>>& ClonedBlobImpls() const
|
||||
{
|
||||
MOZ_ASSERT(mBuffer, "Write() has never been called.");
|
||||
return mBlobImplArray;
|
||||
}
|
||||
|
||||
nsTArray<nsRefPtr<MessagePortBase>>& GetTransferredPorts()
|
||||
{
|
||||
MOZ_ASSERT(!(mFlags & eMessagePortNotSupported));
|
||||
MOZ_ASSERT(mSupportsTransferring);
|
||||
return mTransferredPorts;
|
||||
}
|
||||
|
||||
@ -154,19 +183,12 @@ public:
|
||||
void* aContent,
|
||||
uint64_t aExtraData) override;
|
||||
private:
|
||||
bool StoreISupports(nsISupports* aSupports)
|
||||
{
|
||||
MOZ_ASSERT(aSupports);
|
||||
mSupportsArray.AppendElement(aSupports);
|
||||
return true;
|
||||
}
|
||||
|
||||
// This is our bitmap.
|
||||
uint32_t mFlags;
|
||||
bool mSupportsCloning;
|
||||
bool mSupportsTransferring;
|
||||
|
||||
// Useful for the structured clone algorithm:
|
||||
|
||||
nsTArray<nsCOMPtr<nsISupports>> mSupportsArray;
|
||||
nsTArray<nsRefPtr<BlobImpl>> mBlobImplArray;
|
||||
|
||||
// This raw pointer is set and unset into the ::Read(). It's always null
|
||||
// outside that method. For this reason it's a raw pointer.
|
||||
|
@ -231,12 +231,51 @@ function test_windowToIframeURL(url) {
|
||||
document.body.appendChild(ifr);
|
||||
}
|
||||
|
||||
function test_broadcastChannel() {
|
||||
info("Testing broadcastChannel");
|
||||
|
||||
var bc1 = new BroadcastChannel('postMessagesTest');
|
||||
var bc2 = new BroadcastChannel('postMessagesTest');
|
||||
|
||||
var resolve;
|
||||
|
||||
bc2.onmessage = function(e) {
|
||||
if (!resolve) {
|
||||
ok(false, "Unexpected message!");
|
||||
return;
|
||||
}
|
||||
|
||||
let tmp = resolve;
|
||||
resolve = null;
|
||||
tmp({ data: e.data, ports: [] });
|
||||
}
|
||||
|
||||
runTests({
|
||||
clonableObjects: true,
|
||||
transferableObjects: false,
|
||||
send: function(what, ports) {
|
||||
is(ports.length, 0, "No ports for this test!");
|
||||
return new Promise(function(r, rr) {
|
||||
resolve = r;
|
||||
bc1.postMessage(what);
|
||||
});
|
||||
},
|
||||
|
||||
finished: function() {
|
||||
onmessage = null;
|
||||
next();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var tests = [
|
||||
create_fileList,
|
||||
|
||||
test_windowToWindow,
|
||||
test_windowToIframe,
|
||||
test_windowToCrossOriginIframe,
|
||||
|
||||
test_broadcastChannel,
|
||||
];
|
||||
|
||||
function next() {
|
||||
|
@ -8,7 +8,8 @@
|
||||
#include "BroadcastChannelChild.h"
|
||||
#include "mozilla/dom/BroadcastChannelBinding.h"
|
||||
#include "mozilla/dom/Navigator.h"
|
||||
#include "mozilla/dom/StructuredCloneUtils.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/StructuredCloneHelper.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
@ -30,20 +31,18 @@ namespace dom {
|
||||
|
||||
using namespace workers;
|
||||
|
||||
class BroadcastChannelMessage final
|
||||
class BroadcastChannelMessage final : public StructuredCloneHelper
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(BroadcastChannelMessage)
|
||||
|
||||
JSAutoStructuredCloneBuffer mBuffer;
|
||||
StructuredCloneClosure mClosure;
|
||||
|
||||
BroadcastChannelMessage()
|
||||
{ }
|
||||
: StructuredCloneHelper(CloningSupported, TransferringNotSupported)
|
||||
{}
|
||||
|
||||
private:
|
||||
~BroadcastChannelMessage()
|
||||
{ }
|
||||
{}
|
||||
};
|
||||
|
||||
namespace {
|
||||
@ -166,13 +165,13 @@ public:
|
||||
ClonedMessageData message;
|
||||
|
||||
SerializedStructuredCloneBuffer& buffer = message.data();
|
||||
buffer.data = mData->mBuffer.data();
|
||||
buffer.dataLength = mData->mBuffer.nbytes();
|
||||
buffer.data = mData->BufferData();
|
||||
buffer.dataLength = mData->BufferSize();
|
||||
|
||||
PBackgroundChild* backgroundManager = mActor->Manager();
|
||||
MOZ_ASSERT(backgroundManager);
|
||||
|
||||
const nsTArray<nsRefPtr<BlobImpl>>& blobImpls = mData->mClosure.mBlobImpls;
|
||||
const nsTArray<nsRefPtr<BlobImpl>>& blobImpls = mData->ClonedBlobImpls();
|
||||
|
||||
if (!blobImpls.IsEmpty()) {
|
||||
message.blobsChild().SetCapacity(blobImpls.Length());
|
||||
@ -455,12 +454,12 @@ BroadcastChannel::PostMessageInternal(JSContext* aCx,
|
||||
{
|
||||
nsRefPtr<BroadcastChannelMessage> data = new BroadcastChannelMessage();
|
||||
|
||||
if (!WriteStructuredClone(aCx, aMessage, data->mBuffer, data->mClosure)) {
|
||||
if (!data->Write(aCx, aMessage)) {
|
||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
const nsTArray<nsRefPtr<BlobImpl>>& blobImpls = data->mClosure.mBlobImpls;
|
||||
const nsTArray<nsRefPtr<BlobImpl>>& blobImpls = data->ClonedBlobImpls();
|
||||
for (uint32_t i = 0, len = blobImpls.Length(); i < len; ++i) {
|
||||
if (!blobImpls[i]->MayBeClonedToOtherThreads()) {
|
||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/MessageEvent.h"
|
||||
#include "mozilla/dom/MessageEventBinding.h"
|
||||
#include "mozilla/dom/StructuredCloneUtils.h"
|
||||
#include "mozilla/dom/StructuredCloneHelper.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerScope.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
@ -86,15 +86,15 @@ BroadcastChannelChild::RecvNotify(const ClonedMessageData& aData)
|
||||
}
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
const SerializedStructuredCloneBuffer& buffer = aData.data();
|
||||
StructuredCloneData cloneData;
|
||||
cloneData.mData = buffer.data;
|
||||
cloneData.mDataLength = buffer.dataLength;
|
||||
cloneData.mClosure.mBlobImpls.SwapElements(blobs);
|
||||
StructuredCloneHelper cloneHelper(StructuredCloneHelper::CloningSupported,
|
||||
StructuredCloneHelper::TransferringNotSupported);
|
||||
|
||||
JS::Rooted<JS::Value> value(cx, JS::NullValue());
|
||||
if (cloneData.mDataLength && !ReadStructuredClone(cx, cloneData, &value)) {
|
||||
if (buffer.dataLength &&
|
||||
!cloneHelper.ReadFromBuffer(mBC->GetParentObject(), cx,
|
||||
buffer.data, buffer.dataLength, blobs,
|
||||
&value)) {
|
||||
JS_ClearPendingException(cx);
|
||||
return false;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/PromiseWorkerProxy.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/StructuredCloneHelper.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
|
||||
#include "WorkerPrivate.h"
|
||||
@ -207,8 +208,8 @@ protected:
|
||||
|
||||
// A DataStoreRunnable to run DataStore::Put(...) on the main thread.
|
||||
class DataStorePutRunnable final : public DataStoreProxyRunnable
|
||||
, public StructuredCloneHelper
|
||||
{
|
||||
JSAutoStructuredCloneBuffer mObjBuffer;
|
||||
const StringOrUnsignedLong& mId;
|
||||
const nsString mRevisionId;
|
||||
ErrorResult& mRv;
|
||||
@ -223,6 +224,7 @@ public:
|
||||
const nsAString& aRevisionId,
|
||||
ErrorResult& aRv)
|
||||
: DataStoreProxyRunnable(aWorkerPrivate, aBackingStore, aWorkerPromise)
|
||||
, StructuredCloneHelper(CloningNotSupported, TransferringNotSupported)
|
||||
, mId(aId)
|
||||
, mRevisionId(aRevisionId)
|
||||
, mRv(aRv)
|
||||
@ -231,7 +233,7 @@ public:
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
// This needs to be structured cloned while it's still on the worker thread.
|
||||
if (!mObjBuffer.write(aCx, aObj)) {
|
||||
if (!Write(aCx, aObj)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
mRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
}
|
||||
@ -252,7 +254,7 @@ protected:
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
JS::Rooted<JS::Value> value(cx);
|
||||
if (!mObjBuffer.read(cx, &value)) {
|
||||
if (!Read(mBackingStore->GetParentObject(), cx, &value)) {
|
||||
JS_ClearPendingException(cx);
|
||||
mRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return true;
|
||||
@ -270,8 +272,8 @@ protected:
|
||||
|
||||
// A DataStoreRunnable to run DataStore::Add(...) on the main thread.
|
||||
class DataStoreAddRunnable final : public DataStoreProxyRunnable
|
||||
, public StructuredCloneHelper
|
||||
{
|
||||
JSAutoStructuredCloneBuffer mObjBuffer;
|
||||
const Optional<StringOrUnsignedLong>& mId;
|
||||
const nsString mRevisionId;
|
||||
ErrorResult& mRv;
|
||||
@ -286,6 +288,7 @@ public:
|
||||
const nsAString& aRevisionId,
|
||||
ErrorResult& aRv)
|
||||
: DataStoreProxyRunnable(aWorkerPrivate, aBackingStore, aWorkerPromise)
|
||||
, StructuredCloneHelper(CloningNotSupported, TransferringNotSupported)
|
||||
, mId(aId)
|
||||
, mRevisionId(aRevisionId)
|
||||
, mRv(aRv)
|
||||
@ -294,7 +297,7 @@ public:
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
// This needs to be structured cloned while it's still on the worker thread.
|
||||
if (!mObjBuffer.write(aCx, aObj)) {
|
||||
if (!Write(aCx, aObj)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
mRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
}
|
||||
@ -315,7 +318,7 @@ protected:
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
JS::Rooted<JS::Value> value(cx);
|
||||
if (!mObjBuffer.read(cx, &value)) {
|
||||
if (!Read(mBackingStore->GetParentObject(), cx, &value)) {
|
||||
JS_ClearPendingException(cx);
|
||||
mRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user