mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-08 04:27:37 +00:00
Bug 431465 - Crash [@DecompileExpression] with trap, r/a=shaver
This commit is contained in:
parent
992d7014b9
commit
3a27105df4
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user