Bug 1433642 - Do not free transferables in synthetic clone buffers, r=jorendorff

--HG--
extra : rebase_source : b9b92559fc1b3b226636d24f316fd56da4445233
extra : source : 6b7d7b8605ea2240498f01eab16c0940f6e0cc30
This commit is contained in:
Steve Fink 2018-04-19 22:46:53 -07:00
Родитель e09703704b
Коммит 2cdf0a6db9
2 изменённых файлов: 22 добавлений и 13 удалений

Просмотреть файл

@ -471,6 +471,11 @@ class MOZ_NON_MEMMOVABLE JS_PUBLIC_API(JSStructuredCloneData) {
return bufList_.SizeOfExcludingThis(mallocSizeOf);
}
// Temporary until the scope is moved into JSStructuredCloneData.
void IgnoreTransferables() {
ownTransferables_ = OwnTransferablePolicy::IgnoreTransferablesIfAny;
}
void discardTransferables();
};

Просмотреть файл

@ -2742,13 +2742,14 @@ SetIonCheckGraphCoherency(JSContext* cx, unsigned argc, Value* vp)
return true;
}
// A JSObject that holds structured clone data, similar to the C++ class
// JSAutoStructuredCloneBuffer.
class CloneBufferObject : public NativeObject {
static const JSPropertySpec props_[3];
static const size_t DATA_SLOT = 0;
static const size_t LENGTH_SLOT = 1;
static const size_t SYNTHETIC_SLOT = 2;
static const size_t NUM_SLOTS = 3;
static const size_t SYNTHETIC_SLOT = 1;
static const size_t NUM_SLOTS = 2;
public:
static const Class class_;
@ -2758,7 +2759,6 @@ class CloneBufferObject : public NativeObject {
if (!obj)
return nullptr;
obj->as<CloneBufferObject>().setReservedSlot(DATA_SLOT, PrivateValue(nullptr));
obj->as<CloneBufferObject>().setReservedSlot(LENGTH_SLOT, Int32Value(0));
obj->as<CloneBufferObject>().setReservedSlot(SYNTHETIC_SLOT, BooleanValue(false));
if (!JS_DefineProperties(cx, obj, props_))
@ -2793,14 +2793,15 @@ class CloneBufferObject : public NativeObject {
MOZ_ASSERT(!data());
setReservedSlot(DATA_SLOT, PrivateValue(aData));
setReservedSlot(SYNTHETIC_SLOT, BooleanValue(synthetic));
// Temporary until the scope is moved into JSStructuredCloneData.
if (synthetic)
aData->IgnoreTransferables();
}
// Discard an owned clone buffer.
void discard() {
if (data()) {
JSAutoStructuredCloneBuffer clonebuf(JS::StructuredCloneScope::SameProcessSameThread, nullptr, nullptr);
clonebuf.adopt(Move(*data()));
}
js_delete(data());
setReservedSlot(DATA_SLOT, PrivateValue(nullptr));
}
@ -3083,6 +3084,12 @@ Deserialize(JSContext* cx, unsigned argc, Value* vp)
return false;
}
if (fuzzingSafe && *maybeScope < scope) {
JS_ReportErrorASCII(cx, "Fuzzing builds must not set less restrictive scope "
"than the deserialized clone buffer's scope");
return false;
}
scope = *maybeScope;
}
}
@ -3098,11 +3105,6 @@ Deserialize(JSContext* cx, unsigned argc, Value* vp)
if (!JS_StructuredCloneHasTransferables(*obj->data(), &hasTransferable))
return false;
if (obj->isSynthetic() && scope != JS::StructuredCloneScope::DifferentProcess) {
JS_ReportErrorASCII(cx, "clone buffer data is synthetic but may contain pointers");
return false;
}
RootedValue deserialized(cx);
if (!JS_ReadStructuredClone(cx, *obj->data(),
JS_STRUCTURED_CLONE_VERSION,
@ -3113,6 +3115,8 @@ Deserialize(JSContext* cx, unsigned argc, Value* vp)
}
args.rval().set(deserialized);
// Consume any clone buffer with transferables; throw an error if it is
// deserialized again.
if (hasTransferable)
obj->discard();