コンテキストをまたいでevalでcallerにアクセスできないのはなぜか
~/mozilla/js/src/jsfun.c
static JSBool fun_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { .... case FUN_CALLER: if (fp && fp->down && fp->down->fun) *vp = OBJECT_TO_JSVAL(fp->down->callee); else *vp = JSVAL_NULL; if (!JSVAL_IS_PRIMITIVE(*vp) && cx->runtime->checkObjectAccess) { id = ATOM_KEY(cx->runtime->atomState.callerAtom); if (!cx->runtime->checkObjectAccess(cx, obj, id, JSACC_READ, vp)) return JS_FALSE; } break;
checkObjectAccessを調べると
~/mozilla/js/src/jscntxt.h
/* * Check property accessibility for objects of arbitrary class. Used at * present to check f.caller accessibility for any function object f. */ JSCheckAccessOp checkObjectAccess;
callerのアクセスチェックだけに用意されている。
代入される実体はnsScriptSecurityManager::CheckObjectAccessになっている。
///////////////// Security Checks ///////////////// JSBool JS_DLL_CALLBACK nsScriptSecurityManager::CheckObjectAccess(JSContext *cx, JSObject *obj, jsval id, JSAccessMode mode, jsval *vp) { // Get the security manager nsScriptSecurityManager *ssm = nsScriptSecurityManager::GetScriptSecurityManager(); NS_ASSERTION(ssm, "Failed to get security manager service"); if (!ssm) return JS_FALSE; // Get the object being accessed. We protect these cases: // 1. The Function.prototype.caller property's value, which might lead // an attacker up a call-stack to a function or another object from // a different trust domain. // 2. A user-defined getter or setter function accessible on another // trust domain's window or document object. // *vp can be a primitive, in that case, we use obj as the target // object. JSObject* target = JSVAL_IS_PRIMITIVE(*vp) ? obj : JSVAL_TO_OBJECT(*vp); // Do the same-origin check -- this sets a JS exception if the check fails. // Pass the parent object's class name, as we have no class-info for it. nsresult rv = ssm->CheckPropertyAccess(cx, target, JS_GetClass(cx, obj)->name, id, (mode & JSACC_WRITE) ? nsIXPCSecurityManager::ACCESS_SET_PROPERTY : nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
前回のComponents.classesと同じところでチェックが行われる。
nsIXPCNativeCallContext aCallContextがNULLになってる。
FirebugコンソールからComponents.classesを参照したときはnot NULLだった。名前からすると呼び出し元がネイティブのコードかどうか。
GMの場合scripted functionからなのでnullなのだと予想される。
gmのなかで eval("", arguments.callee.caller) するとclassnameはFunction. subjectのprincipalはsystem.
same originが適用される。
subject principal がページのcodebaseなのにたいしてobject principalはsystem になっていてNG.