Bug 826435 - Do not allow poisoned pointers near a HashTable; r=sfink

The rooting analysis depends on all usage of a poisoned pointer to crash. This
patch makes the above usage crash, as required.

--HG--
extra : rebase_source : 3d67e4c44cee91d889edbf6641cebe9887fb10ee
This commit is contained in:
Terrence Cole 2013-01-03 17:01:38 -08:00
parent 8703bba79a
commit b680b1170a
7 changed files with 21 additions and 12 deletions

View File

@ -470,6 +470,7 @@ struct PointerHasher
{
typedef Key Lookup;
static HashNumber hash(const Lookup &l) {
JS_ASSERT(!js::IsPoisonedPtr(l));
size_t word = reinterpret_cast<size_t>(l) >> zeroBits;
JS_STATIC_ASSERT(sizeof(HashNumber) == 4);
#if JS_BYTES_PER_WORD == 4
@ -480,6 +481,8 @@ struct PointerHasher
#endif
}
static bool match(const Key &k, const Lookup &l) {
JS_ASSERT(!js::IsPoisonedPtr(k));
JS_ASSERT(!js::IsPoisonedPtr(l));
return k == l;
}
};

View File

@ -3238,7 +3238,7 @@ js_InitArrayClass(JSContext *cx, HandleObject obj)
* arrays in JSON and script literals and allows setDenseArrayElement to
* be used without updating the indexed type set for such default arrays.
*/
if (!arrayProto->setNewTypeUnknown(cx))
if (!JSObject::setNewTypeUnknown(cx, arrayProto))
return NULL;
if (!LinkConstructorAndPrototype(cx, ctor, arrayProto))

View File

@ -5841,10 +5841,10 @@ JSObject::hasNewType(TypeObject *type)
}
#endif /* DEBUG */
bool
JSObject::setNewTypeUnknown(JSContext *cx)
/* static */ bool
JSObject::setNewTypeUnknown(JSContext *cx, HandleObject obj)
{
if (!setFlag(cx, js::BaseShape::NEW_TYPE_UNKNOWN))
if (!obj->setFlag(cx, js::BaseShape::NEW_TYPE_UNKNOWN))
return false;
/*
@ -5854,7 +5854,7 @@ JSObject::setNewTypeUnknown(JSContext *cx)
*/
TypeObjectSet &table = cx->compartment->newTypeObjects;
if (table.initialized()) {
if (TypeObjectSet::Ptr p = table.lookup(this))
if (TypeObjectSet::Ptr p = table.lookup(obj.get()))
MarkTypeObjectUnknownProperties(cx, *p);
}

View File

@ -2618,8 +2618,11 @@ js::SetProto(JSContext *cx, HandleObject obj, Handle<js::TaggedProto> proto, boo
return true;
}
if (proto.isObject() && !proto.toObject()->setNewTypeUnknown(cx))
return false;
if (proto.isObject()) {
RootedObject protoObj(cx, proto.toObject());
if (!JSObject::setNewTypeUnknown(cx, protoObj))
return false;
}
TypeObject *type = cx->compartment->getNewType(cx, proto);
if (!type)

View File

@ -476,7 +476,7 @@ struct JSObject : public js::ObjectImpl
* Mark an object as requiring its default 'new' type to have unknown
* properties.
*/
bool setNewTypeUnknown(JSContext *cx);
static bool setNewTypeUnknown(JSContext *cx, JS::HandleObject obj);
/* Set a new prototype for an object with a singleton type. */
bool splicePrototype(JSContext *cx, js::Handle<js::TaggedProto> proto);

View File

@ -3084,8 +3084,11 @@ NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv_, Tag
* their properties and so that we don't need to walk the compartment if
* their prototype changes later.
*/
if (proto.isObject() && !proto.toObject()->setNewTypeUnknown(cx))
return NULL;
if (proto.isObject()) {
RootedObject protoObj(cx, proto.toObject());
if (!JSObject::setNewTypeUnknown(cx, protoObj))
return NULL;
}
RootedObject obj(cx, NewObjectWithGivenProto(cx, clasp, proto, parent));
if (!obj)

View File

@ -200,7 +200,7 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
* to have unknown properties, to simplify handling of e.g. heterogenous
* objects in JSON and script literals.
*/
if (!objectProto->setNewTypeUnknown(cx))
if (!setNewTypeUnknown(cx, objectProto))
return NULL;
/* Create |Function.prototype| next so we can create other functions. */
@ -263,7 +263,7 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
* inference to have unknown properties, to simplify handling of e.g.
* CloneFunctionObject.
*/
if (!functionProto->setNewTypeUnknown(cx))
if (!setNewTypeUnknown(cx, functionProto))
return NULL;
}