Bug 942304 - Avoid rooting hazard in ArrayBufferObject::neuterViews. r=terrence

This commit is contained in:
Steve Fink 2013-11-22 13:07:59 -08:00
parent 9fac0e8934
commit 47623b74b0
2 changed files with 18 additions and 18 deletions

View File

@ -331,12 +331,12 @@ GetViewListRef(ArrayBufferObject *obj)
return reinterpret_cast<OldObjectRepresentationHack*>(obj->getElementsHeader())->views;
}
bool
ArrayBufferObject::neuterViews(JSContext *cx)
/* static */ bool
ArrayBufferObject::neuterViews(JSContext *cx, Handle<ArrayBufferObject*> buffer)
{
ArrayBufferViewObject *view;
size_t numViews = 0;
for (view = GetViewList(this); view; view = view->nextView()) {
for (view = GetViewList(buffer); view; view = view->nextView()) {
numViews++;
view->neuter();
@ -346,26 +346,26 @@ ArrayBufferObject::neuterViews(JSContext *cx)
// neuterAsmJSArrayBuffer adjusts state specific to the ArrayBuffer data
// itself, but it only affects the behavior of views
if (isAsmJSArrayBuffer()) {
if (!ArrayBufferObject::neuterAsmJSArrayBuffer(cx, *this))
if (buffer->isAsmJSArrayBuffer()) {
if (!ArrayBufferObject::neuterAsmJSArrayBuffer(cx, *buffer))
return false;
}
// Remove buffer from the list of buffers with > 1 view.
if (numViews > 1 && GetViewList(this)->bufferLink() != UNSET_BUFFER_LINK) {
ArrayBufferObject *prev = compartment()->gcLiveArrayBuffers;
if (prev == this) {
compartment()->gcLiveArrayBuffers = GetViewList(prev)->bufferLink();
if (numViews > 1 && GetViewList(buffer)->bufferLink() != UNSET_BUFFER_LINK) {
ArrayBufferObject *prev = buffer->compartment()->gcLiveArrayBuffers;
if (prev == buffer) {
buffer->compartment()->gcLiveArrayBuffers = GetViewList(prev)->bufferLink();
} else {
for (ArrayBufferObject *buf = GetViewList(prev)->bufferLink();
buf;
buf = GetViewList(buf)->bufferLink())
for (ArrayBufferObject *b = GetViewList(prev)->bufferLink();
b;
b = GetViewList(b)->bufferLink())
{
if (buf == this) {
GetViewList(prev)->setBufferLink(GetViewList(buf)->bufferLink());
if (b == buffer) {
GetViewList(prev)->setBufferLink(GetViewList(b)->bufferLink());
break;
}
prev = buf;
prev = b;
}
}
}
@ -705,7 +705,7 @@ ArrayBufferObject::stealContents(JSContext *cx, Handle<ArrayBufferObject*> buffe
// Neuter the views, which may also mprotect(PROT_NONE) the buffer. So do
// it after copying out the data.
if (!buffer->neuterViews(cx))
if (!ArrayBufferObject::neuterViews(cx, buffer))
return false;
if (!own) {
@ -4062,7 +4062,7 @@ JS_NeuterArrayBuffer(JSContext *cx, HandleObject obj)
}
Rooted<ArrayBufferObject*> buffer(cx, &obj->as<ArrayBufferObject>());
if (!buffer->neuterViews(cx))
if (!ArrayBufferObject::neuterViews(cx, buffer))
return false;
buffer->neuter(cx);
return true;

View File

@ -198,7 +198,7 @@ class ArrayBufferObject : public JSObject
/*
* Neuter all views of an ArrayBuffer.
*/
bool neuterViews(JSContext *cx);
static bool neuterViews(JSContext *cx, Handle<ArrayBufferObject*> buffer);
inline uint8_t * dataPointer() const {
return (uint8_t *) elements;