Bug 431465 - Crash [@DecompileExpression] with trap, r/a=shaver

This commit is contained in:
crowder@fiverocks.com 2008-05-01 14:36:19 -07:00
parent 860997c4e9
commit aa2f89f028
2 changed files with 50 additions and 18 deletions

View File

@ -105,7 +105,8 @@ js_UntrapScriptCode(JSContext *cx, JSScript *script)
for (trap = (JSTrap *)rt->trapList.next;
trap != (JSTrap *)&rt->trapList;
trap = (JSTrap *)trap->links.next) {
if (trap->script == script) {
if (trap->script == script &&
(size_t)(trap->pc - script->code) < script->length) {
if (code == script->code) {
jssrcnote *sn, *notes;
size_t nbytes;

View File

@ -4617,7 +4617,7 @@ DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len,
code = js_UntrapScriptCode(cx, jp->script);
if (code != oldcode) {
jp->script->code = code;
jp->script->main = code + (oldmain - jp->script->code);
jp->script->main = code + (oldmain - oldcode);
pc = code + (pc - oldcode);
}
@ -4907,6 +4907,7 @@ static char *
DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun,
jsbytecode *pc)
{
jsbytecode *code, *oldcode, *oldmain;
JSOp op;
const JSCodeSpec *cs;
jsbytecode *begin, *end;
@ -4918,10 +4919,19 @@ DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun,
char *name;
JS_ASSERT(script->main <= pc && pc < script->code + script->length);
op = (JSOp) *pc;
if (op == JSOP_TRAP)
op = JS_GetTrapOpcode(cx, script, pc);
pcstack = NULL;
oldcode = script->code;
oldmain = script->main;
/* From this point the control must flow through the label out. */
code = js_UntrapScriptCode(cx, script);
if (code != oldcode) {
script->code = code;
script->main = code + (oldmain - oldcode);
pc = code + (pc - oldcode);
}
op = (JSOp) *pc;
/* None of these stack-writing ops generates novel values. */
JS_ASSERT(op != JSOP_CASE && op != JSOP_CASEX &&
op != JSOP_DUP && op != JSOP_DUP2 &&
@ -4931,8 +4941,10 @@ DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun,
* |this| could convert to a very long object initialiser, so cite it by
* its keyword name instead.
*/
if (op == JSOP_THIS)
return JS_strdup(cx, js_this_str);
if (op == JSOP_THIS) {
name = JS_strdup(cx, js_this_str);
goto out;
}
/*
* JSOP_BINDNAME is special: it generates a value, the base object of a
@ -4940,10 +4952,13 @@ DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun,
* js_DecompileValueGenerator, the name being bound is irrelevant. Just
* fall back to the base object.
*/
if (op == JSOP_BINDNAME)
return FAILED_EXPRESSION_DECOMPILER;
if (op == JSOP_BINDNAME) {
name = FAILED_EXPRESSION_DECOMPILER;
goto out;
}
/* NAME ops are self-contained, others require left or right context. */
name = NULL;
cs = &js_CodeSpec[op];
begin = pc;
end = pc + cs->length;
@ -4954,7 +4969,8 @@ DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun,
case 0:
sn = js_GetSrcNote(script, pc);
if (!sn)
return FAILED_EXPRESSION_DECOMPILER;
name = FAILED_EXPRESSION_DECOMPILER;
goto out;
switch (SN_TYPE(sn)) {
case SRC_PCBASE:
begin -= js_GetSrcNoteOffset(sn, 0);
@ -4964,18 +4980,23 @@ DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun,
begin += cs->length;
break;
default:
return FAILED_EXPRESSION_DECOMPILER;
name = FAILED_EXPRESSION_DECOMPILER;
goto out;
}
break;
default:;
}
len = PTRDIFF(end, begin, jsbytecode);
if (len <= 0)
return FAILED_EXPRESSION_DECOMPILER;
if (len <= 0) {
name = FAILED_EXPRESSION_DECOMPILER;
goto out;
}
pcstack = (jsbytecode **) JS_malloc(cx, script->depth * sizeof *pcstack);
if (!pcstack)
return NULL;
if (!pcstack) {
name = NULL;
goto out;
}
/* From this point the control must flow through the label out. */
pcdepth = ReconstructPCStack(cx, script, begin, pcstack);
@ -4984,7 +5005,6 @@ DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun,
goto out;
}
name = NULL;
jp = JS_NEW_PRINTER(cx, "js_DecompileValueGenerator", fun, 0, JS_FALSE);
if (jp) {
jp->dvgfence = end;
@ -4997,7 +5017,14 @@ DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun,
}
out:
JS_free(cx, pcstack);
if (code != oldcode) {
JS_free(cx, script->code);
script->code = oldcode;
script->main = oldmain;
}
if (pcstack)
JS_free(cx, pcstack);
return name;
}
@ -5198,7 +5225,11 @@ ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *pc,
JS_ASSERT(ndefs == 0);
LOCAL_ASSERT(pcdepth >= 1);
LOCAL_ASSERT(nuses == 0 ||
*pcstack[pcdepth - 1] == JSOP_ENTERBLOCK);
*pcstack[pcdepth - 1] == JSOP_ENTERBLOCK ||
(*pcstack[pcdepth - 1] == JSOP_TRAP &&
JS_GetTrapOpcode(cx, script,
pcstack[pcdepth - 1]) ==
JSOP_ENTERBLOCK));
pcstack[pcdepth - 1] = pc;
break;
}