Bug 1303714 - Always Unwrap ArrayBuffer in TypedArray constructor. r=bholley

This commit is contained in:
Tom Schuster 2016-10-03 21:19:09 +02:00
Родитель 4c034fe691
Коммит 4e49d5103f
2 изменённых файлов: 44 добавлений и 45 удалений

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

@ -765,15 +765,6 @@ class TypedArrayObjectTemplate : public TypedArrayObject
fromBufferWithProto(JSContext* cx, HandleObject bufobj, uint32_t byteOffset, int32_t lengthInt, fromBufferWithProto(JSContext* cx, HandleObject bufobj, uint32_t byteOffset, int32_t lengthInt,
HandleObject proto) HandleObject proto)
{ {
ESClass cls;
if (!GetBuiltinClass(cx, bufobj, &cls))
return nullptr;
if (cls != ESClass::ArrayBuffer && cls != ESClass::SharedArrayBuffer) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
return nullptr;
}
MOZ_ASSERT(IsArrayBuffer(bufobj) || IsSharedArrayBuffer(bufobj) || bufobj->is<ProxyObject>());
if (bufobj->is<ProxyObject>()) { if (bufobj->is<ProxyObject>()) {
/* /*
* Normally, NonGenericMethodGuard handles the case of transparent * Normally, NonGenericMethodGuard handles the case of transparent
@ -791,44 +782,48 @@ class TypedArrayObjectTemplate : public TypedArrayObject
JS_ReportErrorASCII(cx, "Permission denied to access object"); JS_ReportErrorASCII(cx, "Permission denied to access object");
return nullptr; return nullptr;
} }
if (IsArrayBuffer(wrapped) || IsSharedArrayBuffer(wrapped)) {
/*
* And for even more fun, the new view's prototype should be
* set to the origin compartment's prototype object, not the
* target's (specifically, the actual view in the target
* compartment will use as its prototype a wrapper around the
* origin compartment's view.prototype object).
*
* Rather than hack some crazy solution together, implement
* this all using a private helper function, created when
* ArrayBufferObject was initialized and cached in the global.
* This reuses all the existing cross-compartment crazy so we
* don't have to do anything *uniquely* crazy here.
*/
RootedObject protoRoot(cx, proto); if (!IsArrayBuffer(wrapped) && !IsSharedArrayBuffer(wrapped)) {
if (!protoRoot) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
if (!GetBuiltinPrototype(cx, JSCLASS_CACHED_PROTO_KEY(instanceClass()), &protoRoot)) return nullptr; // must be arrayBuffer
return nullptr;
}
FixedInvokeArgs<3> args(cx);
args[0].setNumber(byteOffset);
args[1].setInt32(lengthInt);
args[2].setObject(*protoRoot);
RootedValue fval(cx);
if (!getOrCreateCreateArrayFromBufferFunction(cx, &fval))
return nullptr;
RootedValue thisv(cx, ObjectValue(*bufobj));
RootedValue rval(cx);
if (!js::Call(cx, fval, thisv, args, &rval))
return nullptr;
return &rval.toObject();
} }
/*
* And for even more fun, the new view's prototype should be
* set to the origin compartment's prototype object, not the
* target's (specifically, the actual view in the target
* compartment will use as its prototype a wrapper around the
* origin compartment's view.prototype object).
*
* Rather than hack some crazy solution together, implement
* this all using a private helper function, created when
* ArrayBufferObject was initialized and cached in the global.
* This reuses all the existing cross-compartment crazy so we
* don't have to do anything *uniquely* crazy here.
*/
RootedObject protoRoot(cx, proto);
if (!protoRoot) {
if (!GetBuiltinPrototype(cx, JSCLASS_CACHED_PROTO_KEY(instanceClass()), &protoRoot))
return nullptr;
}
FixedInvokeArgs<3> args(cx);
args[0].setNumber(byteOffset);
args[1].setInt32(lengthInt);
args[2].setObject(*protoRoot);
RootedValue fval(cx);
if (!getOrCreateCreateArrayFromBufferFunction(cx, &fval))
return nullptr;
RootedValue thisv(cx, ObjectValue(*bufobj));
RootedValue rval(cx);
if (!js::Call(cx, fval, thisv, args, &rval))
return nullptr;
return &rval.toObject();
} }
if (!IsArrayBuffer(bufobj) && !IsSharedArrayBuffer(bufobj)) { if (!IsArrayBuffer(bufobj) && !IsSharedArrayBuffer(bufobj)) {

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

@ -753,6 +753,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
is(t.length, 10, "Length accessor works over Xrays") is(t.length, 10, "Length accessor works over Xrays")
is(t.byteLength, t.length * window[c].prototype.BYTES_PER_ELEMENT, "byteLength accessor works over Xrays") is(t.byteLength, t.length * window[c].prototype.BYTES_PER_ELEMENT, "byteLength accessor works over Xrays")
// Can create TypedArray from content ArrayBuffer
var buffer = new iwin.ArrayBuffer(8);
eval(`new ${c}(buffer);`);
var xray = new iwin[c](0); var xray = new iwin[c](0);
var xrayTypedArrayProto = Object.getPrototypeOf(Object.getPrototypeOf(xray)); var xrayTypedArrayProto = Object.getPrototypeOf(Object.getPrototypeOf(xray));
testProtoCallables(inheritedCallables, new iwin[c](0), xrayTypedArrayProto, typedArrayProto); testProtoCallables(inheritedCallables, new iwin[c](0), xrayTypedArrayProto, typedArrayProto);