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)) if (!Valueify(fp)->getValidCalleeObject(cx, &v))
return false; return false;
*vp = v.isObject() ? Jsvalify(v) : JSVAL_VOID;
*vp = Jsvalify(v); *vp = Jsvalify(v);
return true; return true;
} }

View File

@ -1427,7 +1427,7 @@ bool
StackFrame::getValidCalleeObject(JSContext *cx, Value *vp) StackFrame::getValidCalleeObject(JSContext *cx, Value *vp)
{ {
if (!isFunctionFrame()) { if (!isFunctionFrame()) {
vp->setUndefined(); vp->setNull();
return true; return true;
} }
@ -1575,9 +1575,11 @@ fun_getProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
NULL, JSMSG_DEPRECATED_USAGE, js_arguments_str)) { NULL, JSMSG_DEPRECATED_USAGE, js_arguments_str)) {
return false; return false;
} }
if (!js_GetArgsValue(cx, fp, vp))
return false; return js_GetArgsValue(cx, fp, vp);
} else if (JSID_IS_ATOM(id, cx->runtime->atomState.callerAtom)) { }
if (JSID_IS_ATOM(id, cx->runtime->atomState.callerAtom)) {
if (!fp->prev()) if (!fp->prev())
return true; return true;
@ -1585,26 +1587,29 @@ fun_getProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
if (frame && !frame->getValidCalleeObject(cx, vp)) if (frame && !frame->getValidCalleeObject(cx, vp))
return false; return false;
if (vp->isObject()) { if (!vp->isObject()) {
JSObject &caller = vp->toObject(); JS_ASSERT(vp->isNull());
return true;
}
/* Censor the caller if it is from another compartment. */ /* Censor the caller if it is from another compartment. */
if (caller.compartment() != cx->compartment) { JSObject &caller = vp->toObject();
vp->setNull(); if (caller.compartment() != cx->compartment) {
} else if (caller.isFunction()) { vp->setNull();
JSFunction *callerFun = caller.getFunctionPrivate(); } else if (caller.isFunction()) {
if (callerFun->isInterpreted() && callerFun->inStrictMode()) { JSFunction *callerFun = caller.getFunctionPrivate();
JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL, if (callerFun->isInterpreted() && callerFun->inStrictMode()) {
JSMSG_CALLER_IS_STRICT); JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL,
return false; 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 eval-native-callback-is-indirect.js
script extension-methods-reject-null-undefined-this.js script extension-methods-reject-null-undefined-this.js
skip-if(!xulRuntime.shell) script function-definition-with.js # needs evaluate() skip-if(!xulRuntime.shell) script function-definition-with.js # needs evaluate()
script function-properties.js
script iterator-in-catch.js script iterator-in-catch.js
skip-if(!xulRuntime.shell) script legacy-JSON.js # needs parseLegacyJSON skip-if(!xulRuntime.shell) script legacy-JSON.js # needs parseLegacyJSON
fails script nested-delete-name-in-evalcode.js # bug 604301, at a minimum 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 * Compute the callee function for this stack frame, cloning if needed to
* function object, which may require deferred cloning due to the JSObject * implement the method read barrier. If this is not a function frame,
* methodReadBarrier. For a non-function frame, return true with *vp set * set *vp to null.
* from calleev, which may not be an object (it could be undefined).
*/ */
bool getValidCalleeObject(JSContext *cx, Value *vp); bool getValidCalleeObject(JSContext *cx, Value *vp);