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
parent 1de9aa6374
commit c90b0c1084
5 changed files with 54 additions and 2 deletions

View File

@ -2292,6 +2292,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()) {
@ -2398,6 +2404,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()) {

View File

@ -0,0 +1,10 @@
// Test that instantiating a typed array on top of a neutered buffer
// doesn't trip any asserts. Public domain.
if (!this.hasOwnProperty("TypedObject"))
quit();
x = ArrayBuffer();
neuter(x);
Uint32Array(x);
gc();

View File

@ -0,0 +1,23 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 976697;
var {StructType, uint32, Object, Any, storage, objectType} = TypedObject;
function main() { // once a C programmer, always a C programmer.
print(BUGNUMBER + ": " + summary);
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");
reportCompare(true, true);
print("Tests complete");
}
main();

View File

@ -278,7 +278,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);
}

View File

@ -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);