Bug 589318 - guard that eval-in-function frames don't access args (r=brendan)

This commit is contained in:
Luke Wagner 2010-08-21 15:50:14 -07:00
Родитель ec2daad82d
Коммит 53bd429318
4 изменённых файлов: 19 добавлений и 11 удалений

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

@ -293,7 +293,7 @@ InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
stackDepth = 0;
valueCount = 0;
for (fp = js_GetTopStackFrame(cx); fp; fp = fp->down) {
if (fp->hasFunction() && fp->argv) {
if (fp->hasFunction() && fp->argv && !fp->isEvalFrame()) {
Value v = NullValue();
if (checkAccess &&
!checkAccess(cx, fp->callee(), callerid, JSACC_READ, &v)) {
@ -334,7 +334,7 @@ InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
values = GetStackTraceValueBuffer(priv);
elem = priv->stackElems;
for (fp = js_GetTopStackFrame(cx); fp != fpstop; fp = fp->down) {
if (!fp->hasFunction()) {
if (!fp->hasFunction() || fp->isEvalFrame()) {
elem->funName = NULL;
elem->argc = 0;
} else {

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

@ -813,12 +813,13 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
JSObject *initialVarObj;
if (down) {
/* Propagate arg state for eval and the debugger API. */
JS_ASSERT_IF(down->hasFunction(), down->hasCallObj());
fp->setCallObj(down->maybeCallObj());
fp->setArgsObj(NULL);
fp->setFunction((script->staticLevel > 0) ? down->maybeFunction() : NULL);
fp->setThisValue(down->getThisValue());
fp->flags = flags | (down->flags & JSFRAME_COMPUTED_THIS);
fp->setNumActualArgs(down->numActualArgs());
fp->setNumActualArgs(0);
fp->argv = down->argv;
fp->setAnnotation(down->maybeAnnotation());
fp->setScopeChain(chain);

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

@ -160,6 +160,7 @@ struct JSStackFrame
JSObject* getArgsObj() const {
JS_ASSERT(hasArgsObj());
JS_ASSERT(!isEvalFrame());
return argsobj;
}
@ -384,6 +385,7 @@ struct JSStackFrame
}
size_t numFormalArgs() const {
JS_ASSERT(!isEvalFrame());
return getFunction()->nargs;
}
@ -426,6 +428,7 @@ struct JSStackFrame
/* Argument count accessors */
size_t numActualArgs() const {
JS_ASSERT(!isEvalFrame());
return argc;
}
@ -499,6 +502,7 @@ struct JSStackFrame
}
bool isDummyFrame() const { return !!(flags & JSFRAME_DUMMY); }
bool isEvalFrame() const { return !!(flags & JSFRAME_EVAL); }
/* Contains static assertions for member alignment, don't call. */
inline void staticAsserts();

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

@ -1092,7 +1092,13 @@ Tracker::set(const void* v, LIns* i)
static inline jsuint
argSlots(JSStackFrame* fp)
{
return JS_MAX(fp->numActualArgs(), fp->numFormalArgs());
return fp->isEvalFrame() ? 0 : JS_MAX(fp->numActualArgs(), fp->numFormalArgs());
}
static inline jsuint
numEntryFrameArgs(JSStackFrame* fp)
{
return fp->isEvalFrame() ? 0 : fp->numActualArgs();
}
static inline bool
@ -6102,7 +6108,7 @@ AttemptToExtendTree(JSContext* cx, VMSideExit* anchor, VMSideExit* exitedFrom, j
}
JS_ASSERT(ngslots >= anchor->numGlobalSlots);
bool rv = TraceRecorder::startRecorder(cx, anchor, c, stackSlots, ngslots, typeMap,
exitedFrom, outer, cx->fp->numActualArgs(),
exitedFrom, outer, numEntryFrameArgs(cx->fp),
Record_Branch, hits < maxHits);
#ifdef MOZ_TRACEVIS
if (!rv && tvso)
@ -6151,7 +6157,7 @@ TraceRecorder::recordLoopEdge(JSContext* cx, TraceRecorder* r, uintN& inlineCall
JS_ASSERT(r->fragment && !r->fragment->lastIns);
TreeFragment* root = r->fragment->root;
TreeFragment* first = LookupOrAddLoop(tm, cx->regs->pc, root->globalObj,
root->globalShape, cx->fp->numActualArgs());
root->globalShape, numEntryFrameArgs(cx->fp));
/*
* Make sure the shape of the global object still matches (this might flush
@ -6179,7 +6185,7 @@ TraceRecorder::recordLoopEdge(JSContext* cx, TraceRecorder* r, uintN& inlineCall
TreeFragment* outerFragment = root;
jsbytecode* outer = (jsbytecode*) outerFragment->ip;
uint32 outerArgc = outerFragment->argc;
JS_ASSERT(cx->fp->numActualArgs() == first->argc);
JS_ASSERT(numEntryFrameArgs(cx->fp) == first->argc);
AbortRecording(cx, "No compatible inner tree");
return RecordingIfTrue(RecordTree(cx, first, outer, outerArgc, globalSlots, Record_Branch));
@ -7191,7 +7197,7 @@ MonitorLoopEdge(JSContext* cx, uintN& inlineCallCount, RecordReason reason)
}
jsbytecode* pc = cx->regs->pc;
uint32 argc = cx->fp->numActualArgs();
uint32 argc = numEntryFrameArgs(cx->fp);
TreeFragment* f = LookupOrAddLoop(tm, pc, globalObj, globalShape, argc);
@ -8230,19 +8236,16 @@ TraceRecorder::callProp(JSObject* obj, JSProperty* prop, jsid id, Value*& vp,
uintN slot = uint16(sprop->shortid);
vp = NULL;
uintN upvar_slot = SPROP_INVALID_SLOT;
JSStackFrame* cfp = (JSStackFrame*) obj->getPrivate();
if (cfp) {
if (sprop->getterOp() == js_GetCallArg) {
JS_ASSERT(slot < cfp->numFormalArgs());
vp = &cfp->argv[slot];
upvar_slot = slot;
nr.v = *vp;
} else if (sprop->getterOp() == js_GetCallVar ||
sprop->getterOp() == js_GetCallVarChecked) {
JS_ASSERT(slot < cfp->getSlotCount());
vp = &cfp->slots()[slot];
upvar_slot = cx->fp->numFormalArgs() + slot;
nr.v = *vp;
} else {
RETURN_STOP("dynamic property of Call object");