зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1583251 - P3 - Check if it is okay to allow shared memory while deserializing; r=nika,lth
Differential Revision: https://phabricator.services.mozilla.com/D48349 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
c291baa433
Коммит
5ba65c0735
|
@ -162,7 +162,6 @@ PostMessageEvent::Run() {
|
|||
nsCOMPtr<mozilla::dom::EventTarget> eventTarget =
|
||||
do_QueryObject(targetWindow);
|
||||
|
||||
// XXX cloneDataPolicy will be used in P3
|
||||
JS::CloneDataPolicy cloneDataPolicy;
|
||||
MOZ_DIAGNOSTIC_ASSERT(targetWindow);
|
||||
if (mCallerAgentClusterId.isSome() &&
|
||||
|
@ -172,8 +171,8 @@ PostMessageEvent::Run() {
|
|||
|
||||
StructuredCloneHolder* holder;
|
||||
if (mHolder.constructed<StructuredCloneHolder>()) {
|
||||
mHolder.ref<StructuredCloneHolder>().Read(ToSupports(targetWindow), cx,
|
||||
&messageData, rv);
|
||||
mHolder.ref<StructuredCloneHolder>().Read(
|
||||
ToSupports(targetWindow), cx, &messageData, cloneDataPolicy, rv);
|
||||
holder = &mHolder.ref<StructuredCloneHolder>();
|
||||
} else {
|
||||
MOZ_ASSERT(mHolder.constructed<ipc::StructuredCloneData>());
|
||||
|
|
|
@ -190,11 +190,17 @@ bool StructuredCloneHolderBase::Write(JSContext* aCx,
|
|||
|
||||
bool StructuredCloneHolderBase::Read(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aValue) {
|
||||
return Read(aCx, aValue, JS::CloneDataPolicy());
|
||||
}
|
||||
|
||||
bool StructuredCloneHolderBase::Read(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aValue,
|
||||
JS::CloneDataPolicy aCloneDataPolicy) {
|
||||
MOZ_ASSERT(mBuffer, "Read() without Write() is not allowed.");
|
||||
MOZ_ASSERT(!mClearCalled, "This method cannot be called after Clear.");
|
||||
|
||||
bool ok =
|
||||
mBuffer->read(aCx, aValue, &StructuredCloneHolder::sCallbacks, this);
|
||||
bool ok = mBuffer->read(aCx, aValue, aCloneDataPolicy,
|
||||
&StructuredCloneHolder::sCallbacks, this);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -269,6 +275,13 @@ void StructuredCloneHolder::Write(JSContext* aCx, JS::Handle<JS::Value> aValue,
|
|||
void StructuredCloneHolder::Read(nsISupports* aParent, JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aValue,
|
||||
ErrorResult& aRv) {
|
||||
return Read(aParent, aCx, aValue, JS::CloneDataPolicy(), aRv);
|
||||
}
|
||||
|
||||
void StructuredCloneHolder::Read(nsISupports* aParent, JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aValue,
|
||||
JS::CloneDataPolicy aCloneDataPolicy,
|
||||
ErrorResult& aRv) {
|
||||
MOZ_ASSERT_IF(
|
||||
mStructuredCloneScope == StructuredCloneScope::SameProcessSameThread,
|
||||
mCreationEventTarget->IsOnCurrentThread());
|
||||
|
@ -277,7 +290,7 @@ void StructuredCloneHolder::Read(nsISupports* aParent, JSContext* aCx,
|
|||
mozilla::AutoRestore<nsISupports*> guard(mParent);
|
||||
mParent = aParent;
|
||||
|
||||
if (!StructuredCloneHolderBase::Read(aCx, aValue)) {
|
||||
if (!StructuredCloneHolderBase::Read(aCx, aValue, aCloneDataPolicy)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return;
|
||||
|
@ -316,8 +329,8 @@ void StructuredCloneHolder::ReadFromBuffer(nsISupports* aParent, JSContext* aCx,
|
|||
mParent = aParent;
|
||||
|
||||
if (!JS_ReadStructuredClone(aCx, aBuffer, aAlgorithmVersion,
|
||||
mStructuredCloneScope, aValue, &sCallbacks,
|
||||
this)) {
|
||||
mStructuredCloneScope, aValue,
|
||||
JS::CloneDataPolicy(), &sCallbacks, this)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
}
|
||||
|
|
|
@ -104,6 +104,10 @@ class StructuredCloneHolderBase {
|
|||
// aValue.
|
||||
bool Read(JSContext* aCx, JS::MutableHandle<JS::Value> aValue);
|
||||
|
||||
// Like Read() but it supports handling of clone policy.
|
||||
bool Read(JSContext* aCx, JS::MutableHandle<JS::Value> aValue,
|
||||
JS::CloneDataPolicy aCloneDataPolicy);
|
||||
|
||||
bool HasData() const { return !!mBuffer; }
|
||||
|
||||
JSStructuredCloneData& BufferData() const {
|
||||
|
@ -165,6 +169,10 @@ class StructuredCloneHolder : public StructuredCloneHolderBase {
|
|||
void Read(nsISupports* aParent, JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aValue, ErrorResult& aRv);
|
||||
|
||||
void Read(nsISupports* aParent, JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aValue,
|
||||
JS::CloneDataPolicy aCloneDataPolicy, ErrorResult& aRv);
|
||||
|
||||
// Call this method to know if this object is keeping some DOM object alive.
|
||||
bool HasClonedDOMObjects() const {
|
||||
return !mBlobImplArray.IsEmpty() || !mWasmModuleArray.IsEmpty() ||
|
||||
|
|
|
@ -1063,7 +1063,7 @@ bool IDBObjectStore::DeserializeValue(JSContext* aCx,
|
|||
if (!JS_ReadStructuredClone(
|
||||
aCx, aCloneReadInfo.mData, JS_STRUCTURED_CLONE_VERSION,
|
||||
JS::StructuredCloneScope::DifferentProcessForIndexedDB, aValue,
|
||||
&callbacks, &aCloneReadInfo)) {
|
||||
JS::CloneDataPolicy(), &callbacks, &aCloneReadInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1222,7 +1222,7 @@ class DeserializeIndexValueHelper final : public Runnable {
|
|||
if (!JS_ReadStructuredClone(
|
||||
aCx, mCloneReadInfo.mData, JS_STRUCTURED_CLONE_VERSION,
|
||||
JS::StructuredCloneScope::DifferentProcessForIndexedDB, aValue,
|
||||
&callbacks, &mCloneReadInfo)) {
|
||||
JS::CloneDataPolicy(), &callbacks, &mCloneReadInfo)) {
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
|
||||
|
@ -1328,7 +1328,7 @@ class DeserializeUpgradeValueHelper final : public Runnable {
|
|||
if (!JS_ReadStructuredClone(
|
||||
aCx, mCloneReadInfo.mData, JS_STRUCTURED_CLONE_VERSION,
|
||||
JS::StructuredCloneScope::DifferentProcessForIndexedDB, aValue,
|
||||
&callbacks, &mCloneReadInfo)) {
|
||||
JS::CloneDataPolicy(), &callbacks, &mCloneReadInfo)) {
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
|
||||
|
|
|
@ -543,6 +543,7 @@ class MOZ_NON_MEMMOVABLE JS_PUBLIC_API JSStructuredCloneData {
|
|||
JS_PUBLIC_API bool JS_ReadStructuredClone(
|
||||
JSContext* cx, JSStructuredCloneData& data, uint32_t version,
|
||||
JS::StructuredCloneScope scope, JS::MutableHandleValue vp,
|
||||
JS::CloneDataPolicy cloneDataPolicy,
|
||||
const JSStructuredCloneCallbacks* optionalCallbacks, void* closure);
|
||||
|
||||
/**
|
||||
|
@ -632,6 +633,7 @@ class JS_PUBLIC_API JSAutoStructuredCloneBuffer {
|
|||
}
|
||||
|
||||
bool read(JSContext* cx, JS::MutableHandleValue vp,
|
||||
JS::CloneDataPolicy cloneDataPolicy = JS::CloneDataPolicy(),
|
||||
const JSStructuredCloneCallbacks* optionalCallbacks = nullptr,
|
||||
void* closure = nullptr);
|
||||
|
||||
|
|
|
@ -3498,7 +3498,8 @@ static bool Deserialize(JSContext* cx, unsigned argc, Value* vp) {
|
|||
|
||||
RootedValue deserialized(cx);
|
||||
if (!JS_ReadStructuredClone(cx, *obj->data(), JS_STRUCTURED_CLONE_VERSION,
|
||||
scope, &deserialized, nullptr, nullptr)) {
|
||||
scope, &deserialized, JS::CloneDataPolicy(),
|
||||
nullptr, nullptr)) {
|
||||
return false;
|
||||
}
|
||||
args.rval().set(deserialized);
|
||||
|
|
|
@ -54,9 +54,10 @@ static int testStructuredCloneReaderFuzz(const uint8_t* buf, size_t size) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
JS::CloneDataPolicy policy;
|
||||
RootedValue deserialized(gCx);
|
||||
if (!JS_ReadStructuredClone(gCx, *clonebuf, JS_STRUCTURED_CLONE_VERSION,
|
||||
scope, &deserialized, nullptr, nullptr)) {
|
||||
scope, &deserialized, policy, nullptr, nullptr)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -70,7 +71,6 @@ static int testStructuredCloneReaderFuzz(const uint8_t* buf, size_t size) {
|
|||
Tests show that this also doesn't cause a serious performance penalty.
|
||||
*/
|
||||
mozilla::Maybe<JSAutoStructuredCloneBuffer> clonebufOut;
|
||||
JS::CloneDataPolicy policy;
|
||||
|
||||
clonebufOut.emplace(scope, nullptr, nullptr);
|
||||
if (!clonebufOut->write(gCx, deserialized, UndefinedHandleValue, policy)) {
|
||||
|
|
|
@ -137,7 +137,7 @@ bool TestCloneObject() {
|
|||
JS::RootedValue v1(cx, JS::ObjectValue(*obj1));
|
||||
CHECK(cloned_buffer.write(cx, v1, nullptr, nullptr));
|
||||
JS::RootedValue v2(cx);
|
||||
CHECK(cloned_buffer.read(cx, &v2, nullptr, nullptr));
|
||||
CHECK(cloned_buffer.read(cx, &v2, JS::CloneDataPolicy(), nullptr, nullptr));
|
||||
JS::RootedObject obj2(cx, v2.toObjectOrNull());
|
||||
CHECK(VerifyObject(obj2, 8, 12, false));
|
||||
|
||||
|
@ -173,10 +173,10 @@ bool TestTransferObject() {
|
|||
|
||||
JSAutoStructuredCloneBuffer cloned_buffer(
|
||||
JS::StructuredCloneScope::SameProcessSameThread, nullptr, nullptr);
|
||||
CHECK(cloned_buffer.write(cx, v1, transferable, JS::CloneDataPolicy(),
|
||||
nullptr, nullptr));
|
||||
JS::CloneDataPolicy policy;
|
||||
CHECK(cloned_buffer.write(cx, v1, transferable, policy, nullptr, nullptr));
|
||||
JS::RootedValue v2(cx);
|
||||
CHECK(cloned_buffer.read(cx, &v2, nullptr, nullptr));
|
||||
CHECK(cloned_buffer.read(cx, &v2, policy, nullptr, nullptr));
|
||||
JS::RootedObject obj2(cx, v2.toObjectOrNull());
|
||||
CHECK(VerifyObject(obj2, 8, 12, true));
|
||||
CHECK(JS::IsDetachedArrayBufferObject(obj1));
|
||||
|
|
|
@ -386,10 +386,12 @@ class SCInput {
|
|||
struct JSStructuredCloneReader {
|
||||
public:
|
||||
explicit JSStructuredCloneReader(SCInput& in, JS::StructuredCloneScope scope,
|
||||
JS::CloneDataPolicy cloneDataPolicy,
|
||||
const JSStructuredCloneCallbacks* cb,
|
||||
void* cbClosure)
|
||||
: in(in),
|
||||
allowedScope(scope),
|
||||
cloneDataPolicy(cloneDataPolicy),
|
||||
objs(in.context()),
|
||||
allObjs(in.context()),
|
||||
callbacks(cb),
|
||||
|
@ -430,6 +432,8 @@ struct JSStructuredCloneReader {
|
|||
// be valid cross-process.)
|
||||
JS::StructuredCloneScope allowedScope;
|
||||
|
||||
const JS::CloneDataPolicy cloneDataPolicy;
|
||||
|
||||
// Stack of objects with properties remaining to be read.
|
||||
RootedValueVector objs;
|
||||
|
||||
|
@ -637,10 +641,11 @@ bool WriteStructuredClone(JSContext* cx, HandleValue v,
|
|||
|
||||
bool ReadStructuredClone(JSContext* cx, JSStructuredCloneData& data,
|
||||
JS::StructuredCloneScope scope, MutableHandleValue vp,
|
||||
JS::CloneDataPolicy cloneDataPolicy,
|
||||
const JSStructuredCloneCallbacks* cb,
|
||||
void* cbClosure) {
|
||||
SCInput in(cx, data);
|
||||
JSStructuredCloneReader r(in, scope, cb, cbClosure);
|
||||
JSStructuredCloneReader r(in, scope, cloneDataPolicy, cb, cbClosure);
|
||||
return r.read(vp);
|
||||
}
|
||||
|
||||
|
@ -2211,6 +2216,12 @@ bool JSStructuredCloneReader::readArrayBuffer(uint32_t nbytes,
|
|||
}
|
||||
|
||||
bool JSStructuredCloneReader::readSharedArrayBuffer(MutableHandleValue vp) {
|
||||
if (!cloneDataPolicy.isSharedArrayBufferAllowed()) {
|
||||
JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr,
|
||||
JSMSG_SC_NOT_CLONABLE, "SharedArrayBuffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t byteLength;
|
||||
if (!in.readBytes(&byteLength, sizeof(byteLength))) {
|
||||
return in.reportTruncated();
|
||||
|
@ -2257,14 +2268,19 @@ bool JSStructuredCloneReader::readSharedArrayBuffer(MutableHandleValue vp) {
|
|||
|
||||
bool JSStructuredCloneReader::readSharedWasmMemory(uint32_t nbytes,
|
||||
MutableHandleValue vp) {
|
||||
JSContext* cx = context();
|
||||
if (nbytes != 0) {
|
||||
JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr,
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_SC_BAD_SERIALIZED_DATA,
|
||||
"invalid shared wasm memory tag");
|
||||
return false;
|
||||
}
|
||||
|
||||
JSContext* cx = context();
|
||||
if (!cloneDataPolicy.isSharedArrayBufferAllowed()) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_SC_NOT_CLONABLE, "WebAssembly.Memory");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the SharedArrayBuffer object.
|
||||
RootedValue payload(cx);
|
||||
|
@ -3008,6 +3024,7 @@ using namespace js;
|
|||
JS_PUBLIC_API bool JS_ReadStructuredClone(
|
||||
JSContext* cx, JSStructuredCloneData& buf, uint32_t version,
|
||||
JS::StructuredCloneScope scope, MutableHandleValue vp,
|
||||
JS::CloneDataPolicy cloneDataPolicy,
|
||||
const JSStructuredCloneCallbacks* optionalCallbacks, void* closure) {
|
||||
AssertHeapIsIdle();
|
||||
CHECK_THREAD(cx);
|
||||
|
@ -3018,7 +3035,8 @@ JS_PUBLIC_API bool JS_ReadStructuredClone(
|
|||
return false;
|
||||
}
|
||||
const JSStructuredCloneCallbacks* callbacks = optionalCallbacks;
|
||||
return ReadStructuredClone(cx, buf, scope, vp, callbacks, closure);
|
||||
return ReadStructuredClone(cx, buf, scope, vp, cloneDataPolicy, callbacks,
|
||||
closure);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API bool JS_WriteStructuredClone(
|
||||
|
@ -3082,7 +3100,7 @@ JS_PUBLIC_API bool JS_StructuredClone(
|
|||
}
|
||||
}
|
||||
|
||||
return buf.read(cx, vp, callbacks, closure);
|
||||
return buf.read(cx, vp, JS::CloneDataPolicy(), callbacks, closure);
|
||||
}
|
||||
|
||||
JSAutoStructuredCloneBuffer::JSAutoStructuredCloneBuffer(
|
||||
|
@ -3139,11 +3157,11 @@ void JSAutoStructuredCloneBuffer::steal(
|
|||
}
|
||||
|
||||
bool JSAutoStructuredCloneBuffer::read(
|
||||
JSContext* cx, MutableHandleValue vp,
|
||||
JSContext* cx, MutableHandleValue vp, JS::CloneDataPolicy cloneDataPolicy,
|
||||
const JSStructuredCloneCallbacks* optionalCallbacks, void* closure) {
|
||||
MOZ_ASSERT(cx);
|
||||
return !!JS_ReadStructuredClone(cx, data_, version_, scope_, vp,
|
||||
optionalCallbacks, closure);
|
||||
cloneDataPolicy, optionalCallbacks, closure);
|
||||
}
|
||||
|
||||
bool JSAutoStructuredCloneBuffer::write(
|
||||
|
|
Загрузка…
Ссылка в новой задаче