Bug 976697 - Detect neutered buffers in typed array / typed object constructors r=sfink

This commit is contained in:
Nicholas D. Matsakis 2014-02-26 11:55:34 -05:00
Родитель 7e5ea1b4bb
Коммит f79094d312
5 изменённых файлов: 57 добавлений и 2 удалений

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

@ -2301,6 +2301,12 @@ TypedObject::constructSized(JSContext *cx, unsigned int argc, Value *vp)
Rooted<ArrayBufferObject*> buffer(cx);
buffer = &args[0].toObject().as<ArrayBufferObject>();
if (buffer->isNeutered()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage,
nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
return false;
}
int32_t offset;
if (args.length() >= 2 && !args[1].isUndefined()) {
if (!args[1].isInt32()) {
@ -2407,6 +2413,12 @@ TypedObject::constructUnsized(JSContext *cx, unsigned int argc, Value *vp)
Rooted<ArrayBufferObject*> buffer(cx);
buffer = &args[0].toObject().as<ArrayBufferObject>();
if (buffer->isNeutered()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage,
nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
return false;
}
int32_t offset;
if (args.length() >= 2 && !args[1].isUndefined()) {
if (!args[1].isInt32()) {

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

@ -0,0 +1,23 @@
// Bug 976697. Check for various quirks when instantiating a typed
// object atop an already neutered buffer.
if (typeof TypedObject === "undefined")
quit();
load(libdir + "asserts.js")
var {StructType, uint32, Object, Any, storage, objectType} = TypedObject;
function main() { // once a C programmer, always a C programmer.
var Uints = uint32.array();
var Unit = new StructType({}); // Empty struct type
var buffer = new ArrayBuffer(0); // Empty buffer
var p = new Unit(buffer); // OK
neuter(buffer);
assertThrowsInstanceOf(() => new Unit(buffer), TypeError,
"Able to instantiate atop neutered buffer");
assertThrowsInstanceOf(() => new Uints(buffer, 0), TypeError,
"Able to instantiate atop neutered buffer");
}
main();

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

@ -0,0 +1,13 @@
// Test that instantiating a typed array on top of a neutered buffer
// doesn't trip any asserts.
//
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
if (!this.hasOwnProperty("TypedObject"))
quit();
x = ArrayBuffer();
neuter(x);
Uint32Array(x);
gc();

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

@ -302,7 +302,14 @@ InitArrayBufferViewDataPointer(ArrayBufferViewObject *obj, ArrayBufferObject *bu
* private data rather than a slot to avoid alignment restrictions
* on private Values.
*/
obj->initPrivate(buffer->dataPointer() + byteOffset);
if (buffer->isNeutered()) {
JS_ASSERT(byteOffset == 0);
obj->initPrivate(nullptr);
} else {
obj->initPrivate(buffer->dataPointer() + byteOffset);
}
PostBarrierTypedArrayObject(obj);
}

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

@ -362,7 +362,7 @@ class TypedArrayObjectTemplate : public TypedArrayObject
uint32_t bufferByteLength = buffer->byteLength();
uint32_t arrayByteLength = obj->byteLength();
uint32_t arrayByteOffset = obj->byteOffset();
JS_ASSERT(buffer->dataPointer() <= obj->viewData());
JS_ASSERT_IF(!buffer->isNeutered(), buffer->dataPointer() <= obj->viewData());
JS_ASSERT(bufferByteLength - arrayByteOffset >= arrayByteLength);
JS_ASSERT(arrayByteOffset <= bufferByteLength);