Bug 773108 - Avoid overflowing blockid in CompExprTransplanter (r=dvander)

This commit is contained in:
Luke Wagner 2012-07-11 22:07:25 -07:00
Родитель ecbebd6e01
Коммит 112a3cced0
3 изменённых файлов: 31 добавлений и 8 удалений

Просмотреть файл

@ -5033,13 +5033,18 @@ BumpStaticLevel(ParseNode *pn, TreeContext *tc)
return pn->pn_cookie.set(tc->sc->context, level, pn->pn_cookie.slot()); return pn->pn_cookie.set(tc->sc->context, level, pn->pn_cookie.slot());
} }
static void static bool
AdjustBlockId(ParseNode *pn, unsigned adjust, TreeContext *tc) AdjustBlockId(ParseNode *pn, unsigned adjust, TreeContext *tc)
{ {
JS_ASSERT(pn->isArity(PN_LIST) || pn->isArity(PN_FUNC) || pn->isArity(PN_NAME)); JS_ASSERT(pn->isArity(PN_LIST) || pn->isArity(PN_FUNC) || pn->isArity(PN_NAME));
if (JS_BIT(20) - pn->pn_blockid <= adjust + 1) {
JS_ReportErrorNumber(tc->sc->context, js_GetErrorMessage, NULL, JSMSG_NEED_DIET, "program");
return false;
}
pn->pn_blockid += adjust; pn->pn_blockid += adjust;
if (pn->pn_blockid >= tc->blockidGen) if (pn->pn_blockid >= tc->blockidGen)
tc->blockidGen = pn->pn_blockid + 1; tc->blockidGen = pn->pn_blockid + 1;
return true;
} }
bool bool
@ -5056,8 +5061,10 @@ CompExprTransplanter::transplant(ParseNode *pn)
if (!transplant(pn2)) if (!transplant(pn2))
return false; return false;
} }
if (pn->pn_pos >= root->pn_pos) if (pn->pn_pos >= root->pn_pos) {
AdjustBlockId(pn, adjust, tc); if (!AdjustBlockId(pn, adjust, tc))
return false;
}
break; break;
case PN_TERNARY: case PN_TERNARY:
@ -5142,7 +5149,8 @@ CompExprTransplanter::transplant(ParseNode *pn)
if (dn->isPlaceholder() && dn->pn_pos >= root->pn_pos && dn->dn_uses == pn) { if (dn->isPlaceholder() && dn->pn_pos >= root->pn_pos && dn->dn_uses == pn) {
if (genexp && !BumpStaticLevel(dn, tc)) if (genexp && !BumpStaticLevel(dn, tc))
return false; return false;
AdjustBlockId(dn, adjust, tc); if (!AdjustBlockId(dn, adjust, tc))
return false;
} }
RootedAtom atom(parser->context, pn->pn_atom); RootedAtom atom(parser->context, pn->pn_atom);
@ -5203,7 +5211,8 @@ CompExprTransplanter::transplant(ParseNode *pn)
if (genexp && !visitedImplicitArguments.has(dn)) { if (genexp && !visitedImplicitArguments.has(dn)) {
if (!BumpStaticLevel(dn, tc)) if (!BumpStaticLevel(dn, tc))
return false; return false;
AdjustBlockId(dn, adjust, tc); if (!AdjustBlockId(dn, adjust, tc))
return false;
if (!visitedImplicitArguments.put(dn)) if (!visitedImplicitArguments.put(dn))
return false; return false;
} }
@ -5211,8 +5220,10 @@ CompExprTransplanter::transplant(ParseNode *pn)
} }
} }
if (pn->pn_pos >= root->pn_pos) if (pn->pn_pos >= root->pn_pos) {
AdjustBlockId(pn, adjust, tc); if (!AdjustBlockId(pn, adjust, tc))
return false;
}
break; break;
case PN_NAMESET: case PN_NAMESET:
@ -5292,7 +5303,8 @@ Parser::comprehensionTail(ParseNode *kid, unsigned blockid, bool isGenexp,
if (!transplanter.init()) if (!transplanter.init())
return NULL; return NULL;
transplanter.transplant(kid); if (!transplanter.transplant(kid))
return false;
JS_ASSERT(tc->blockChain && tc->blockChain == pn->pn_objbox->object); JS_ASSERT(tc->blockChain && tc->blockChain == pn->pn_objbox->object);
data.initLet(HoistVars, *tc->blockChain, JSMSG_ARRAY_INIT_TOO_BIG); data.initLet(HoistVars, *tc->blockChain, JSMSG_ARRAY_INIT_TOO_BIG);

Просмотреть файл

@ -30,6 +30,7 @@ frontend::GenerateBlockId(TreeContext *tc, uint32_t &blockid)
JS_ReportErrorNumber(tc->sc->context, js_GetErrorMessage, NULL, JSMSG_NEED_DIET, "program"); JS_ReportErrorNumber(tc->sc->context, js_GetErrorMessage, NULL, JSMSG_NEED_DIET, "program");
return false; return false;
} }
JS_ASSERT(tc->blockidGen < JS_BIT(20));
blockid = tc->blockidGen++; blockid = tc->blockidGen++;
return true; return true;
} }

Просмотреть файл

@ -0,0 +1,10 @@
// |jit-test| error:InternalError
Function("\
for each(l in[(let(c)([])\
for each(l in[]))(let(c)w for(u in[]))(let(u)w for(l in[]))(let(c)w for(u in[]))\
(let(u)w for each(l in[]))(let(c)w for(u in[]))(let(u)w for(l in[]))(let(c)w for(u in[]))\
(let(l)w for(l in[]))(let(u)w for(l in['']))(let(c)w for(u in[]))(let(u)w for(l in[]))\
(let(c)w for(l in[]))(let(l)w for(l in[]))(let(c)w for(l in[]))(let(u)w for(l in[]))\
(let(c)w for(l in[]))(let(u)w for each(l in[x]))(let(w,x)w for(u in[]))]){}\
")