mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Protect js_ConstructObject callers from gc hazards and some other stuff. bug 325425, r=igor sr=brendan
This commit is contained in:
parent
f4445bd103
commit
7d72129844
@ -286,3 +286,4 @@ MSG_DEF(JSMSG_BAD_SURROGATE_CHAR, 203, 1, JSEXN_TYPEERR, "bad surrogate char
|
||||
MSG_DEF(JSMSG_UTF8_CHAR_TOO_LARGE, 204, 1, JSEXN_TYPEERR, "UTF-8 character {0} too large")
|
||||
MSG_DEF(JSMSG_MALFORMED_UTF8_CHAR, 205, 1, JSEXN_TYPEERR, "malformed UTF-8 character sequence at offset {0}")
|
||||
MSG_DEF(JSMSG_USER_DEFINED_ERROR, 206, 0, JSEXN_ERR, "JS_ReportError was called")
|
||||
MSG_DEF(JSMSG_WRONG_CONSTRUCTOR, 207, 1, JSEXN_TYPEERR, "wrong construtor called for {0}")
|
||||
|
@ -2126,13 +2126,18 @@ js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
|
||||
JSObject *parent, uintN argc, jsval *argv)
|
||||
{
|
||||
jsval cval, rval;
|
||||
JSTempValueRooter tvr;
|
||||
JSTempValueRooter argtvr, tvr;
|
||||
JSObject *obj, *ctor;
|
||||
|
||||
if (!js_FindConstructor(cx, parent, clasp->name, &cval))
|
||||
JS_PUSH_TEMP_ROOT(cx, argc, argv, &argtvr);
|
||||
|
||||
if (!js_FindConstructor(cx, parent, clasp->name, &cval)) {
|
||||
JS_POP_TEMP_ROOT(cx, &argtvr);
|
||||
return NULL;
|
||||
}
|
||||
if (JSVAL_IS_PRIMITIVE(cval)) {
|
||||
js_ReportIsNotFunction(cx, &cval, JSV2F_CONSTRUCT | JSV2F_SEARCH_STACK);
|
||||
JS_POP_TEMP_ROOT(cx, &argtvr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -2141,7 +2146,6 @@ js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
|
||||
* this point, all control flow must exit through label out with obj set.
|
||||
*/
|
||||
JS_PUSH_SINGLE_TEMP_ROOT(cx, cval, &tvr);
|
||||
obj = NULL;
|
||||
|
||||
/*
|
||||
* If proto or parent are NULL, set them to Constructor.prototype and/or
|
||||
@ -2155,6 +2159,7 @@ js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
|
||||
ATOM_TO_JSID(cx->runtime->atomState
|
||||
.classPrototypeAtom),
|
||||
&rval)) {
|
||||
obj = NULL;
|
||||
goto out;
|
||||
}
|
||||
if (JSVAL_IS_OBJECT(rval))
|
||||
@ -2165,17 +2170,37 @@ js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
|
||||
if (!obj)
|
||||
goto out;
|
||||
|
||||
if (!js_InternalConstruct(cx, obj, cval, argc, argv, &rval)) {
|
||||
cx->newborn[GCX_OBJECT] = NULL;
|
||||
obj = NULL;
|
||||
if (!js_InternalConstruct(cx, obj, cval, argc, argv, &rval))
|
||||
goto bad;
|
||||
|
||||
if (JSVAL_IS_PRIMITIVE(rval))
|
||||
goto out;
|
||||
obj = JSVAL_TO_OBJECT(rval);
|
||||
|
||||
/*
|
||||
* If the given class has both the JSCLASS_HAS_PRIVATE and the
|
||||
* JSCLASS_CONSTRUCT_PROTOTYPE flags, then the class should have its private
|
||||
* data set. If it doesn't, then it means the constructor was replaced, and
|
||||
* we should throw a typerr.
|
||||
*/
|
||||
if (OBJ_GET_CLASS(cx, obj) != clasp ||
|
||||
(!(~clasp->flags & (JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_CONSTRUCT_PROTOTYPE)) &&
|
||||
!JS_GetPrivate(cx, obj))) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_WRONG_CONSTRUCTOR, clasp->name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!JSVAL_IS_PRIMITIVE(rval))
|
||||
obj = JSVAL_TO_OBJECT(rval);
|
||||
out:
|
||||
JS_POP_TEMP_ROOT(cx, &tvr);
|
||||
JS_POP_TEMP_ROOT(cx, &argtvr);
|
||||
return obj;
|
||||
|
||||
bad:
|
||||
cx->newborn[GCX_OBJECT] = NULL;
|
||||
obj = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user