Bug 667646 - fun.caller should be null, not undefined, when fun is being called by global code. r=evilpie

This commit is contained in:
Jeff Walden 2011-06-27 15:57:50 -07:00
parent d938b446a3
commit 1bfc2c45f1
5 changed files with 50 additions and 23 deletions

View File

@ -1592,6 +1592,7 @@ JS_GetValidFrameCalleeObject(JSContext *cx, JSStackFrame *fp, jsval *vp)
if (!Valueify(fp)->getValidCalleeObject(cx, &v))
return false;
*vp = v.isObject() ? Jsvalify(v) : JSVAL_VOID;
*vp = Jsvalify(v);
return true;
}

View File

@ -1427,7 +1427,7 @@ bool
StackFrame::getValidCalleeObject(JSContext *cx, Value *vp)
{
if (!isFunctionFrame()) {
vp->setUndefined();
vp->setNull();
return true;
}
@ -1575,9 +1575,11 @@ fun_getProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
NULL, JSMSG_DEPRECATED_USAGE, js_arguments_str)) {
return false;
}
if (!js_GetArgsValue(cx, fp, vp))
return false;
} else if (JSID_IS_ATOM(id, cx->runtime->atomState.callerAtom)) {
return js_GetArgsValue(cx, fp, vp);
}
if (JSID_IS_ATOM(id, cx->runtime->atomState.callerAtom)) {
if (!fp->prev())
return true;
@ -1585,26 +1587,29 @@ fun_getProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
if (frame && !frame->getValidCalleeObject(cx, vp))
return false;
if (vp->isObject()) {
JSObject &caller = vp->toObject();
if (!vp->isObject()) {
JS_ASSERT(vp->isNull());
return true;
}
/* Censor the caller if it is from another compartment. */
if (caller.compartment() != cx->compartment) {
vp->setNull();
} else if (caller.isFunction()) {
JSFunction *callerFun = caller.getFunctionPrivate();
if (callerFun->isInterpreted() && callerFun->inStrictMode()) {
JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL,
JSMSG_CALLER_IS_STRICT);
return false;
}
/* Censor the caller if it is from another compartment. */
JSObject &caller = vp->toObject();
if (caller.compartment() != cx->compartment) {
vp->setNull();
} else if (caller.isFunction()) {
JSFunction *callerFun = caller.getFunctionPrivate();
if (callerFun->isInterpreted() && callerFun->inStrictMode()) {
JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL,
JSMSG_CALLER_IS_STRICT);
return false;
}
}
} else {
JS_NOT_REACHED("fun_getProperty");
return true;
}
return true;
JS_NOT_REACHED("fun_getProperty");
return false;
}

View File

@ -0,0 +1,21 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
function foo()
{
assertEq(foo.arguments.length, 0);
assertEq(foo.caller, null);
}
assertEq(foo.arguments, null);
assertEq(foo.caller, null);
foo();
assertEq(foo.arguments, null);
assertEq(foo.caller, null);
/******************************************************************************/
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");

View File

@ -14,6 +14,7 @@ skip-if(!xulRuntime.shell) script cross-global-eval-is-indirect.js # needs newGl
script eval-native-callback-is-indirect.js
script extension-methods-reject-null-undefined-this.js
skip-if(!xulRuntime.shell) script function-definition-with.js # needs evaluate()
script function-properties.js
script iterator-in-catch.js
skip-if(!xulRuntime.shell) script legacy-JSON.js # needs parseLegacyJSON
fails script nested-delete-name-in-evalcode.js # bug 604301, at a minimum

View File

@ -741,10 +741,9 @@ class StackFrame
}
/*
* getValidCalleeObject is a fallible getter to compute the correct callee
* function object, which may require deferred cloning due to the JSObject
* methodReadBarrier. For a non-function frame, return true with *vp set
* from calleev, which may not be an object (it could be undefined).
* Compute the callee function for this stack frame, cloning if needed to
* implement the method read barrier. If this is not a function frame,
* set *vp to null.
*/
bool getValidCalleeObject(JSContext *cx, Value *vp);