Bug 354135: protect against oo recursion in e4x. r,a=brendan, a1.9b3=mtschrep

This commit is contained in:
igor@mir2.org 2008-01-31 22:01:17 -08:00
parent 8a3cf9ab35
commit b80ad65983
8 changed files with 32 additions and 59 deletions

View File

@ -521,12 +521,8 @@ array_join_sub(JSContext *cx, JSObject *obj, enum ArrayToStringOp op,
JSString *str;
JSHashEntry *he;
JSAtom *atom;
int stackDummy;
if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
js_ReportOverRecursed(cx);
return JS_FALSE;
}
JS_CHECK_RECURSION(cx, return JS_FALSE);
ok = js_GetLengthProperty(cx, obj, &length);
if (!ok)

View File

@ -967,6 +967,16 @@ js_ReportOutOfScriptQuota(JSContext *cx);
extern void
js_ReportOverRecursed(JSContext *cx);
#define JS_CHECK_RECURSION(cx, onerror) \
JS_BEGIN_MACRO \
int stackDummy_; \
\
if (!JS_CHECK_STACK_SIZE(cx, stackDummy_)) { \
js_ReportOverRecursed(cx); \
onerror; \
} \
JS_END_MACRO
/*
* Report an exception using a previously composed JSErrorReport.
* XXXbe remove from "friend" API

View File

@ -3953,12 +3953,8 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
JSOp op;
JSTokenType type;
uint32 argc;
int stackDummy;
if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
js_ReportOverRecursed(cx);
return JS_FALSE;
}
JS_CHECK_RECURSION(cx, return JS_FALSE);
ok = JS_TRUE;
cg->emitLevel++;

View File

@ -1142,16 +1142,11 @@ JSBool
js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval,
JSAccessMode mode, uintN argc, jsval *argv, jsval *rval)
{
int stackDummy;
/*
* js_InternalInvoke could result in another try to get or set the same id
* again, see bug 355497.
*/
if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
js_ReportOverRecursed(cx);
return JS_FALSE;
}
JS_CHECK_RECURSION(cx, return JS_FALSE);
/*
* Check general (not object-ops/class-specific) access from the running

View File

@ -343,12 +343,8 @@ MarkSharpObjects(JSContext *cx, JSObject *obj, JSIdArray **idap)
uintN attrs;
#endif
jsval val;
int stackDummy;
if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
js_ReportOverRecursed(cx);
return NULL;
}
JS_CHECK_RECURSION(cx, return NULL);
map = &cx->sharpObjectMap;
table = map->table;
@ -628,12 +624,8 @@ obj_toSource(JSContext *cx, uintN argc, jsval *vp)
JSString *gsopold[2];
JSString *gsop[2];
JSString *idstr, *valstr, *str;
int stackDummy;
if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
js_ReportOverRecursed(cx);
return JS_FALSE;
}
JS_CHECK_RECURSION(cx, return JS_FALSE);
/* After this, control must flow through out: to exit. */
JS_PUSH_TEMP_ROOT(cx, 4, localroot, &tvr);
@ -4540,12 +4532,8 @@ js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom,
jsid id;
jsval fval;
JSBool ok;
int stackDummy;
if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
js_ReportOverRecursed(cx);
return JS_FALSE;
}
JS_CHECK_RECURSION(cx, return JS_FALSE);
/*
* Report failure only if an appropriate method was found, and calling it

View File

@ -1602,7 +1602,6 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
#define inXML JS_FALSE
#endif
jsval val;
int stackDummy;
static const char exception_cookie[] = "/*EXCEPTION*/";
static const char retsub_pc_cookie[] = "/*RETSUB_PC*/";
@ -1687,10 +1686,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
JS_END_MACRO
cx = ss->sprinter.context;
if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
js_ReportOverRecursed(cx);
return NULL;
}
JS_CHECK_RECURSION(cx, return NULL);
jp = ss->printer;
startpc = pc;

View File

@ -149,15 +149,6 @@ static JSParenParser ParenExpr;
} \
JS_END_MACRO
#define CHECK_RECURSION() \
JS_BEGIN_MACRO \
int stackDummy; \
if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) { \
js_ReportOverRecursed(cx); \
return NULL; \
} \
JS_END_MACRO
#ifdef METER_PARSENODES
static uint32 parsenodes = 0;
static uint32 maxparsenodes = 0;
@ -1451,7 +1442,7 @@ Statements(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
JSParseNode *pn, *pn2, *saveBlock;
JSTokenType tt;
CHECK_RECURSION();
JS_CHECK_RECURSION(cx, return NULL);
pn = NewParseNode(cx, ts, PN_LIST, tc);
if (!pn)
@ -2387,7 +2378,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
JSStmtInfo stmtInfo, *stmt, *stmt2;
JSAtom *label;
CHECK_RECURSION();
JS_CHECK_RECURSION(cx, return NULL);
ts->flags |= TSF_OPERAND;
tt = js_GetToken(cx, ts);
@ -3655,7 +3646,7 @@ AssignExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
JSTokenType tt;
JSOp op;
CHECK_RECURSION();
JS_CHECK_RECURSION(cx, return NULL);
#if JS_HAS_GENERATORS
ts->flags |= TSF_OPERAND;
@ -4010,7 +4001,7 @@ UnaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
JSTokenType tt;
JSParseNode *pn, *pn2;
CHECK_RECURSION();
JS_CHECK_RECURSION(cx, return NULL);
ts->flags |= TSF_OPERAND;
tt = js_GetToken(cx, ts);
@ -4400,7 +4391,7 @@ MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
JSParseNode *pn, *pn2, *pn3;
JSTokenType tt;
CHECK_RECURSION();
JS_CHECK_RECURSION(cx, return NULL);
/* Check for new expression first. */
ts->flags |= TSF_OPERAND;
@ -5063,7 +5054,7 @@ XMLElementOrList(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
JSTokenType tt;
JSAtom *startAtom, *endAtom;
CHECK_RECURSION();
JS_CHECK_RECURSION(cx, return NULL);
JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_XMLSTAGO);
pn = NewParseNode(cx, ts, PN_LIST, tc);
@ -5264,11 +5255,14 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
{
JSParseNode *pn, *pn2, *pn3;
JSOp op;
#if JS_HAS_SHARP_VARS
JSParseNode *defsharp;
JSBool notsharp;
#endif
JS_CHECK_RECURSION(cx, return NULL);
#if JS_HAS_SHARP_VARS
defsharp = NULL;
notsharp = JS_FALSE;
again:
@ -5279,8 +5273,6 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
*/
#endif
CHECK_RECURSION();
#if JS_HAS_GETTER_SETTER
if (tt == TOK_NAME) {
tt = CheckGetterOrSetter(cx, ts, TOK_FUNCTION);
@ -6226,12 +6218,8 @@ JSBool
js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
{
JSParseNode *pn1 = NULL, *pn2 = NULL, *pn3 = NULL;
int stackDummy;
if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
js_ReportOverRecursed(cx);
return JS_FALSE;
}
JS_CHECK_RECURSION(cx, return JS_FALSE);
switch (pn->pn_arity) {
case PN_FUNC:

View File

@ -3432,6 +3432,8 @@ DeepCopyInLRS(JSContext *cx, JSXML *xml, uintN flags)
/* Our caller must be protecting newborn objects. */
JS_ASSERT(cx->localRootStack);
JS_CHECK_RECURSION(cx, return JS_FALSE);
copy = js_NewXML(cx, (JSXMLClass) xml->xml_class);
if (!copy)
return NULL;
@ -3533,6 +3535,8 @@ DescendantsHelper(JSContext *cx, JSXML *xml, JSXMLQName *nameqn, JSXML *list)
uint32 i, n;
JSXML *attr, *kid;
JS_CHECK_RECURSION(cx, return JS_FALSE);
if (xml->xml_class == JSXML_CLASS_ELEMENT &&
OBJ_GET_CLASS(cx, nameqn->object) == &js_AttributeNameClass) {
for (i = 0, n = xml->xml_attrs.length; i < n; i++) {