Bug 504877 - Check for UniversalXPConnect access further down on the stack chain. r=jst sr=bzbarsky

This commit is contained in:
Blake Kaplan 2009-08-06 20:25:13 -07:00
Родитель 0f2fd7938b
Коммит 30d21cb3c9
10 изменённых файлов: 225 добавлений и 70 удалений

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

@ -5069,13 +5069,10 @@ nsContentUtils::CanAccessNativeAnon()
fp = nsnull;
}
void *annotation = fp ? JS_GetFrameAnnotation(cx, fp) : nsnull;
PRBool privileged;
if (NS_SUCCEEDED(principal->IsCapabilityEnabled("UniversalXPConnect",
annotation,
&privileged)) &&
if (NS_SUCCEEDED(sSecurityManager->IsSystemPrincipal(principal, &privileged)) &&
privileged) {
// UniversalXPConnect things are allowed to touch us.
// Chrome things are allowed to touch us.
return PR_TRUE;
}
@ -5089,6 +5086,12 @@ nsContentUtils::CanAccessNativeAnon()
return PR_TRUE;
}
// Before we throw, check for UniversalXPConnect.
nsresult rv = sSecurityManager->IsCapabilityEnabled("UniversalXPConnect", &privileged);
if (NS_SUCCEEDED(rv) && privileged) {
return PR_TRUE;
}
return PR_FALSE;
}

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

@ -100,7 +100,7 @@ JSExtendedClass sXPC_XOW_JSClass = {
// JSClass (JSExtendedClass.base) initialization
{ "XPCCrossOriginWrapper",
JSCLASS_NEW_RESOLVE | JSCLASS_IS_EXTENDED |
JSCLASS_HAS_RESERVED_SLOTS(XPCWrapper::sNumSlots + 1),
JSCLASS_HAS_RESERVED_SLOTS(XPCWrapper::sNumSlots + 2),
XPC_XOW_AddProperty, XPC_XOW_DelProperty,
XPC_XOW_GetProperty, XPC_XOW_SetProperty,
XPC_XOW_Enumerate, (JSResolveOp)XPC_XOW_NewResolve,
@ -130,6 +130,7 @@ JSExtendedClass sXPC_XOW_JSClass = {
// then the map is about to be destroyed anyway, so we don't need to
// do anything.
static const int XPC_XOW_ScopeSlot = XPCWrapper::sNumSlots;
static const int sUXPCObjectSlot = XPCWrapper::sNumSlots + 1;
static JSBool
XPC_XOW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
@ -242,8 +243,9 @@ IsValFrame(JSObject *obj, jsval v, XPCWrappedNative *wn)
// returns NS_ERROR_DOM_PROP_ACCESS_DENIED, returns another error code on
// failure.
nsresult
CanAccessWrapper(JSContext *cx, JSObject *wrappedObj)
CanAccessWrapper(JSContext *cx, JSObject *wrappedObj, JSBool *privilegeEnabled)
{
// TODO bug 508928: Refactor this with the XOW security checking code.
// Get the subject principal from the execution stack.
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
if (!ssm) {
@ -263,6 +265,10 @@ CanAccessWrapper(JSContext *cx, JSObject *wrappedObj)
nsresult rv = ssm->IsSystemPrincipal(subjectPrin, &isSystem);
NS_ENSURE_SUCCESS(rv, rv);
if (privilegeEnabled) {
*privilegeEnabled = JS_FALSE;
}
// If we somehow end up being called from chrome, just allow full access.
// This can happen from components with xpcnativewrappers=no.
// Note that this is just an optimization to avoid getting the
@ -271,18 +277,6 @@ CanAccessWrapper(JSContext *cx, JSObject *wrappedObj)
return NS_OK;
}
// There might be no code running, but if there is, we need to see if it is
// UniversalXPConnect enabled code.
if (fp) {
void *annotation = JS_GetFrameAnnotation(cx, fp);
rv = subjectPrin->IsCapabilityEnabled("UniversalXPConnect", annotation,
&isSystem);
NS_ENSURE_SUCCESS(rv, rv);
if (isSystem) {
return NS_OK;
}
}
nsCOMPtr<nsIPrincipal> objectPrin;
rv = ssm->GetObjectPrincipal(cx, wrappedObj, getter_AddRefs(objectPrin));
if (NS_FAILED(rv)) {
@ -299,7 +293,17 @@ CanAccessWrapper(JSContext *cx, JSObject *wrappedObj)
PRBool subsumes;
rv = subjectPrin->Subsumes(objectPrin, &subsumes);
if (NS_SUCCEEDED(rv) && !subsumes) {
rv = NS_ERROR_DOM_PROP_ACCESS_DENIED;
// We're about to fail, but make a last effort to see if
// UniversalXPConnect was enabled anywhere else on the stack.
rv = ssm->IsCapabilityEnabled("UniversalXPConnect", &isSystem);
if (NS_SUCCEEDED(rv) && isSystem) {
rv = NS_OK;
if (privilegeEnabled) {
*privilegeEnabled = JS_TRUE;
}
} else {
rv = NS_ERROR_DOM_PROP_ACCESS_DENIED;
}
}
return rv;
}
@ -344,7 +348,7 @@ XPC_XOW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return ThrowException(NS_ERROR_FAILURE, cx);
}
nsresult rv = CanAccessWrapper(cx, JSVAL_TO_OBJECT(funToCall));
nsresult rv = CanAccessWrapper(cx, JSVAL_TO_OBJECT(funToCall), nsnull);
if (NS_FAILED(rv) && rv != NS_ERROR_DOM_PROP_ACCESS_DENIED) {
return ThrowException(rv, cx);
}
@ -511,9 +515,6 @@ XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp,
return JS_TRUE;
}
// FIXME: bug 408871, Note that we create outerObj with a null parent
// here. We set it later so that we find our nominal prototype in the
// same scope as the one that is calling us.
outerObj = JS_NewObjectWithGivenProto(cx, &sXPC_XOW_JSClass.base, nsnull,
parent);
if (!outerObj) {
@ -562,7 +563,8 @@ XPC_XOW_AddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
return ThrowException(NS_ERROR_FAILURE, cx);
}
nsresult rv = CanAccessWrapper(cx, wrappedObj);
JSBool privilegeEnabled = JS_FALSE;
nsresult rv = CanAccessWrapper(cx, wrappedObj, &privilegeEnabled);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) {
// Can't override properties on foreign objects.
@ -588,7 +590,7 @@ XPC_XOW_DelProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
return ThrowException(NS_ERROR_FAILURE, cx);
}
nsresult rv = CanAccessWrapper(cx, wrappedObj);
nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) {
// Can't delete properties on foreign objects.
@ -637,7 +639,9 @@ XPC_XOW_GetOrSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
if (!wrappedObj) {
return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx);
}
nsresult rv = CanAccessWrapper(cx, wrappedObj);
JSBool privilegeEnabled;
nsresult rv = CanAccessWrapper(cx, wrappedObj, &privilegeEnabled);
if (NS_FAILED(rv)) {
if (rv != NS_ERROR_DOM_PROP_ACCESS_DENIED) {
return JS_FALSE;
@ -750,7 +754,7 @@ XPC_XOW_Enumerate(JSContext *cx, JSObject *obj)
return ThrowException(NS_ERROR_FAILURE, cx);
}
nsresult rv = CanAccessWrapper(cx, wrappedObj);
nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) {
// Can't enumerate on foreign objects.
@ -763,6 +767,72 @@ XPC_XOW_Enumerate(JSContext *cx, JSObject *obj)
return XPCWrapper::Enumerate(cx, obj, wrappedObj);
}
// Because of the drastically different ways that same- and cross-origin XOWs
// work, we have to call JS_ClearScope when a XOW changes from being same-
// origin to cross-origin. Normally, there are defined places in Gecko where
// this happens and they notify us. However, UniversalXPConnect causes the
// same transition without any notifications. We could try to detect when this
// happens, but doing so would require calling JS_ClearScope from random
// hooks, which is bad.
//
// The compromise is the UXPCObject. When resolving a property on a XOW as
// same-origin because of UniversalXPConnect, we actually resolve it on the
// UXPCObject (which is just a XOW for the same object). This causes the JS
// engine to do all of its work on another object, not polluting the main
// object. However, if the get results in calling a setter, the engine still
// uses the regular object as 'this', ensuring that the UXPCObject doesn't
// leak to script.
static JSObject *
GetUXPCObject(JSContext *cx, JSObject *obj)
{
NS_ASSERTION(STOBJ_GET_CLASS(obj) == &sXPC_XOW_JSClass.base, "wrong object");
jsval v;
if (!JS_GetReservedSlot(cx, obj, XPCWrapper::sFlagsSlot, &v)) {
return nsnull;
}
if (HAS_FLAGS(v, FLAG_IS_UXPC_OBJECT)) {
return obj;
}
if (!JS_GetReservedSlot(cx, obj, sUXPCObjectSlot, &v)) {
return nsnull;
}
if (JSVAL_IS_OBJECT(v)) {
return JSVAL_TO_OBJECT(v);
}
JSObject *uxpco =
JS_NewObjectWithGivenProto(cx, &sXPC_XOW_JSClass.base, nsnull,
STOBJ_GET_PARENT(obj));
if (!uxpco) {
return nsnull;
}
JSAutoTempValueRooter tvr(cx, uxpco);
jsval wrappedObj, parentScope;
if (!JS_GetReservedSlot(cx, obj, XPCWrapper::sWrappedObjSlot, &wrappedObj) ||
!JS_GetReservedSlot(cx, obj, XPC_XOW_ScopeSlot, &parentScope)) {
return nsnull;
}
if (!JS_SetReservedSlot(cx, uxpco, XPCWrapper::sWrappedObjSlot, wrappedObj) ||
!JS_SetReservedSlot(cx, uxpco, XPCWrapper::sFlagsSlot,
INT_TO_JSVAL(FLAG_IS_UXPC_OBJECT)) ||
!JS_SetReservedSlot(cx, uxpco, XPC_XOW_ScopeSlot, parentScope)) {
return nsnull;
}
if (!JS_SetReservedSlot(cx, obj, sUXPCObjectSlot, OBJECT_TO_JSVAL(uxpco))) {
return nsnull;
}
return uxpco;
}
static JSBool
XPC_XOW_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
JSObject **objp)
@ -781,7 +851,8 @@ XPC_XOW_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
return ThrowException(NS_ERROR_FAILURE, cx);
}
nsresult rv = CanAccessWrapper(cx, wrappedObj);
JSBool privilegeEnabled;
nsresult rv = CanAccessWrapper(cx, wrappedObj, &privilegeEnabled);
if (NS_FAILED(rv)) {
if (rv != NS_ERROR_DOM_PROP_ACCESS_DENIED) {
return JS_FALSE;
@ -800,9 +871,10 @@ XPC_XOW_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
if (!ssm) {
return ThrowException(NS_ERROR_NOT_INITIALIZED, cx);
}
PRUint32 action = (flags & JSRESOLVE_ASSIGNING)
? (PRUint32)nsIXPCSecurityManager::ACCESS_SET_PROPERTY
: (PRUint32)nsIXPCSecurityManager::ACCESS_GET_PROPERTY;
? XPCWrapper::sSecMgrSetProp
: XPCWrapper::sSecMgrGetProp;
rv = ssm->CheckPropertyAccess(cx, wrappedObj,
STOBJ_GET_CLASS(wrappedObj)->name,
id, action);
@ -818,6 +890,10 @@ XPC_XOW_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
}
if (privilegeEnabled && !(obj = GetUXPCObject(cx, obj))) {
return JS_FALSE;
}
if (id == GetRTStringByIndex(cx, XPCJSRuntime::IDX_TO_STRING)) {
jsval oldSlotVal;
if (!JS_GetReservedSlot(cx, obj, XPCWrapper::sFlagsSlot, &oldSlotVal) ||
@ -869,7 +945,7 @@ XPC_XOW_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
}
// Note: JSTYPE_VOID and JSTYPE_STRING are equivalent.
nsresult rv = CanAccessWrapper(cx, wrappedObj);
nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull);
if (NS_FAILED(rv) &&
(rv != NS_ERROR_DOM_PROP_ACCESS_DENIED ||
(type != JSTYPE_STRING && type != JSTYPE_VOID))) {
@ -943,7 +1019,7 @@ XPC_XOW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
return ThrowException(NS_ERROR_FAILURE, cx);
}
nsresult rv = CanAccessWrapper(cx, wrappedObj);
nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) {
// Can't call.
@ -980,7 +1056,7 @@ XPC_XOW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return ThrowException(NS_ERROR_FAILURE, cx);
}
nsresult rv = CanAccessWrapper(cx, wrappedObj);
nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) {
// Can't construct.
@ -1007,7 +1083,7 @@ XPC_XOW_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
return ThrowException(NS_ERROR_FAILURE, cx);
}
nsresult rv = CanAccessWrapper(cx, iface);
nsresult rv = CanAccessWrapper(cx, iface, nsnull);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) {
// Don't do this test across origins.
@ -1093,7 +1169,7 @@ XPC_XOW_Iterator(JSContext *cx, JSObject *obj, JSBool keysonly)
return nsnull;
}
nsresult rv = CanAccessWrapper(cx, wrappedObj);
nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) {
// Can't create iterators for foreign objects.
@ -1160,7 +1236,7 @@ XPC_XOW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return ThrowException(NS_ERROR_FAILURE, cx);
}
nsresult rv = CanAccessWrapper(cx, wrappedObj);
nsresult rv = CanAccessWrapper(cx, wrappedObj, nsnull);
if (rv == NS_ERROR_DOM_PROP_ACCESS_DENIED) {
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
if (!ssm) {

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

@ -214,17 +214,14 @@ EnsureLegalActivity(JSContext *cx, JSObject *obj,
JSStackFrame *fp;
nsIPrincipal *subjectPrincipal = ssm->GetCxSubjectPrincipalAndFrame(cx, &fp);
if (!subjectPrincipal || !fp) {
// We must allow the access if there is no code running.
// We must allow access if there is no code running.
return JS_TRUE;
}
// This might be chrome code or content code with UniversalXPConnect.
void *annotation = JS_GetFrameAnnotation(cx, fp);
PRBool isPrivileged = PR_FALSE;
nsresult rv = subjectPrincipal->IsCapabilityEnabled("UniversalXPConnect",
annotation,
&isPrivileged);
if (NS_SUCCEEDED(rv) && isPrivileged) {
PRBool isSystem;
if (NS_SUCCEEDED(ssm->IsSystemPrincipal(subjectPrincipal, &isSystem)) &&
isSystem) {
// Chrome code is running.
return JS_TRUE;
}
@ -236,6 +233,13 @@ EnsureLegalActivity(JSContext *cx, JSObject *obj,
PRBool subsumes;
if (NS_FAILED(subjectPrincipal->Subsumes(objectPrincipal, &subsumes)) ||
!subsumes) {
// This might be chrome code or content code with UniversalXPConnect.
PRBool isPrivileged = PR_FALSE;
nsresult rv =
ssm->IsCapabilityEnabled("UniversalXPConnect", &isPrivileged);
if (NS_SUCCEEDED(rv) && isPrivileged) {
return JS_TRUE;
}
JSObject* flatObj;
if (!JSVAL_IS_VOID(id) &&
@ -291,32 +295,20 @@ XPCNativeWrapper::GetWrappedNative(JSContext *cx, JSObject *obj,
return JS_TRUE;
}
JSStackFrame *fp;
nsIPrincipal *subjectPrincipal = ssm->GetCxSubjectPrincipalAndFrame(cx, &fp);
nsIPrincipal *subjectPrincipal = ssm->GetCxSubjectPrincipal(cx);
if (!subjectPrincipal) {
return JS_TRUE;
}
if (fp) {
void *annotation = JS_GetFrameAnnotation(cx, fp);
PRBool isPrivileged;
nsresult rv =
subjectPrincipal->IsCapabilityEnabled("UniversalXPConnect",
annotation,
&isPrivileged);
if (NS_SUCCEEDED(rv) && isPrivileged) {
return JS_TRUE;
}
}
XPCWrappedNativeScope *scope = wn->GetScope();
nsIPrincipal *objectPrincipal = scope->GetPrincipal();
PRBool subsumes;
nsresult rv = subjectPrincipal->Subsumes(objectPrincipal, &subsumes);
if (NS_FAILED(rv) || !subsumes) {
return JS_FALSE;
PRBool isPrivileged;
rv = ssm->IsCapabilityEnabled("UniversalXPConnect", &isPrivileged);
return NS_SUCCEEDED(rv) && isPrivileged;
}
return JS_TRUE;

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

@ -136,6 +136,7 @@ FindPrincipals(JSContext *cx, JSObject *obj, nsIPrincipal **objectPrincipal,
static PRBool
CanCallerAccess(JSContext *cx, JSObject *unsafeObj)
{
// TODO bug 508928: Refactor this with the XOW security checking code.
nsCOMPtr<nsIPrincipal> subjPrincipal, objPrincipal;
nsCOMPtr<nsIScriptSecurityManager> ssm;
nsresult rv = FindPrincipals(cx, unsafeObj, getter_AddRefs(objPrincipal),

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

@ -164,6 +164,7 @@ GetWrappedObject(JSContext *cx, JSObject *wrapper)
JSBool
AllowedToAct(JSContext *cx, jsval idval)
{
// TODO bug 508928: Refactor this with the XOW security checking code.
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
if (!ssm) {
return JS_TRUE;
@ -189,13 +190,10 @@ AllowedToAct(JSContext *cx, jsval idval)
fp = nsnull;
}
void *annotation = fp ? JS_GetFrameAnnotation(cx, fp) : nsnull;
PRBool privileged;
if (NS_SUCCEEDED(principal->IsCapabilityEnabled("UniversalXPConnect",
annotation,
&privileged)) &&
if (NS_SUCCEEDED(ssm->IsSystemPrincipal(principal, &privileged)) &&
privileged) {
// UniversalXPConnect things are allowed to touch us.
// Chrome things are allowed to touch us.
return JS_TRUE;
}
@ -209,6 +207,12 @@ AllowedToAct(JSContext *cx, jsval idval)
return JS_TRUE;
}
// Before we throw, check for UniversalXPConnect.
nsresult rv = ssm->IsCapabilityEnabled("UniversalXPConnect", &privileged);
if (NS_SUCCEEDED(rv) && privileged) {
return JS_TRUE;
}
if (JSVAL_IS_VOID(idval)) {
ThrowException(NS_ERROR_XPC_SECURITY_MANAGER_VETO, cx);
} else {

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

@ -82,7 +82,7 @@ XPCWrapper::Unwrap(JSContext *cx, JSObject *wrapper)
if (clasp == &sXPC_SJOW_JSClass.base) {
JSObject *wrappedObj = STOBJ_GET_PARENT(wrapper);
if (NS_FAILED(CanAccessWrapper(cx, wrappedObj))) {
if (NS_FAILED(CanAccessWrapper(cx, wrappedObj, nsnull))) {
JS_ClearPendingException(cx);
return nsnull;

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

@ -51,6 +51,9 @@
// FLAG_RESOLVING is used to tag an XPCNativeWrapper when while it's calling
// the newResolve hook on the XPCWrappedNative's scriptable info.
#define FLAG_RESOLVING 0x4
// FLAG_IS_UXPC_OBJECT is used to tag a XPCCrossOriginWrapper that we created
// to deal with a cross origin XOW that has UniversalXPConnect privileges.
#define FLAG_IS_UXPC_OBJECT (1 << 29)
#define HAS_FLAGS(_val, _flags) \
((PRUint32(JSVAL_TO_INT(_val)) & (_flags)) != 0)
@ -79,7 +82,7 @@ XPC_XOW_WrapperMoved(JSContext *cx, XPCWrappedNative *innerObj,
XPCWrappedNativeScope *newScope);
nsresult
CanAccessWrapper(JSContext *cx, JSObject *wrappedObj);
CanAccessWrapper(JSContext *cx, JSObject *wrappedObj, JSBool *privilegeEnabled);
// Used by UnwrapSOW below.
JSBool
@ -282,7 +285,7 @@ public:
return nsnull;
}
nsresult rv = CanAccessWrapper(cx, wrapper);
nsresult rv = CanAccessWrapper(cx, wrapper, nsnull);
if (NS_FAILED(rv)) {
JS_ClearPendingException(cx);
wrapper = nsnull;
@ -297,7 +300,7 @@ public:
return nsnull;
}
nsresult rv = CanAccessWrapper(cx, wrapper);
nsresult rv = CanAccessWrapper(cx, wrapper, nsnull);
if (NS_FAILED(rv)) {
JS_ClearPendingException(cx);
wrapper = nsnull;

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

@ -47,6 +47,7 @@ include $(topsrcdir)/config/rules.mk
_TEST_FILES = bug500931_helper.html \
inner.html \
bug92773_helper.html \
bug504877_helper.html \
test_bug92773.html \
test_bug361111.xul \
test_bug384632.html \
@ -64,6 +65,7 @@ _TEST_FILES = bug500931_helper.html \
test_bug500691.html \
test_bug502959.html \
test_bug503926.html \
test_bug504877.html \
test_bug505915.html \
test_bug517163.html \
test_cows.html \

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

@ -0,0 +1,7 @@
<html>
<head>
<script>
foopy = 42;
</script>
</head>
</html>

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

@ -0,0 +1,67 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=504877
-->
<head>
<title>Test for Bug 504877</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=504877">Mozilla Bug 504877</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 504877 **/
SimpleTest.waitForExplicitFinish();
var p = 0;
function go() {
var ifr = $('ifr').contentWindow;
function test1() {
try {
ifr.foopy;
ok(false, "should have thrown a cross-origin access exception");
} catch (e) {
ok(/Permission denied/.test(e), "Threw a permission denied exception");
}
var loc = ifr.location;
(function() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
try {
ifr.blat = 42;
} catch (e) {
ok(/UniversalXPConnect/.test(e), "not able to set properties using UniversalXPConnect");
}
is(ifr.foopy, 42, "able to use UniversalXPConnect to get random properties");
loc.replace; // resolves the property onto the wrapper.
})();
loc.replace("http://localhost:8888/");
ok(true, "able to set location on the cross origin(!) frame");
}
function test2() {
SimpleTest.finish();
}
switch (++p) {
case 1: return test1();
case 2: return test2();
}
}
</script>
</pre>
<iframe src="http://example.org/tests/js/src/xpconnect/tests/mochitest/bug504877_helper.html" id="ifr" onload="go()"></iframe>
</body>
</html>