Bug 505915 - Throw exceptions eagerly when we try to convert a cross-origin security wrapper to a C++ object. r=jst

This commit is contained in:
Blake Kaplan 2009-09-02 17:25:25 -07:00
Родитель 98bbb4ab84
Коммит a73bd5ca03
6 изменённых файлов: 111 добавлений и 48 удалений

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

@ -215,6 +215,15 @@ public:
return JS_TRUE;
}
static JSBool IsSecurityWrapper(JSObject *wrapper)
{
JSClass *clasp = STOBJ_GET_CLASS(wrapper);
return clasp == &sXPC_COW_JSClass.base ||
clasp == &sXPC_SJOW_JSClass.base ||
clasp == &sXPC_SOW_JSClass.base ||
clasp == &sXPC_XOW_JSClass.base;
}
/**
* Given an arbitrary object, Unwrap will return the wrapped object if the
* passed-in object is a wrapper that Unwrap knows about *and* the

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

@ -149,24 +149,6 @@ XPCConvert::IsMethodReflectable(const XPTMethodDescriptor& info)
/***************************************************************************/
// static
JSBool
XPCConvert::GetISupportsFromJSObject(JSObject* obj, nsISupports** iface)
{
JSClass* jsclass = STOBJ_GET_CLASS(obj);
NS_ASSERTION(jsclass, "obj has no class");
if(jsclass &&
(jsclass->flags & JSCLASS_HAS_PRIVATE) &&
(jsclass->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS))
{
*iface = (nsISupports*) xpc_GetJSPrivate(obj);
return JS_TRUE;
}
return JS_FALSE;
}
/***************************************************************************/
static void
FinalizeXPCOMUCString(JSContext *cx, JSString *str)
{
@ -1459,9 +1441,27 @@ XPCConvert::JSObject2NativeInterface(XPCCallContext& ccx,
// wrappedNative or other wise has 'nsISupportness'.
// This allows wrapJSAggregatedToNative to work.
// If we're looking at a security wrapper, see now if we're allowed to
// pass it to C++. If we are, then fall through to the code below. If
// we aren't, throw an exception eagerly.
JSObject* inner = nsnull;
if(XPCWrapper::IsSecurityWrapper(src))
{
inner = XPCWrapper::Unwrap(cx, src);
if(!inner)
{
if(pErr)
*pErr = NS_ERROR_XPC_SECURITY_MANAGER_VETO;
return JS_FALSE;
}
}
// Is this really a native xpcom object with a wrapper?
XPCWrappedNative* wrappedNative =
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, src);
XPCWrappedNative::GetWrappedNativeOfJSObject(cx,
inner
? inner
: src);
if(wrappedNative)
{
iface = wrappedNative->GetIdentityObject();
@ -1474,17 +1474,6 @@ XPCConvert::JSObject2NativeInterface(XPCCallContext& ccx,
// DOM <-> E4X bindings are complete, see bug 270553
if(JS_TypeOfValue(cx, OBJECT_TO_JSVAL(src)) == JSTYPE_XML)
return JS_FALSE;
// Does the JSObject have 'nsISupportness'?
// XXX hmm, I wonder if this matters anymore with no
// oldstyle DOM objects around.
if(GetISupportsFromJSObject(src, &iface))
{
if(iface)
return NS_SUCCEEDED(iface->QueryInterface(*iid, dest));
return JS_FALSE;
}
}
// else...

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

@ -3037,7 +3037,6 @@ public:
const nsID* iid,
nsISupports* aOuter,
nsresult* pErr);
static JSBool GetISupportsFromJSObject(JSObject* obj, nsISupports** iface);
/**
* Convert a native array into a jsval.

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

@ -839,6 +839,13 @@ xpc_qsUnwrapThisImpl(JSContext *cx,
jsval *vp,
XPCLazyCallContext *lccx)
{
if(XPCWrapper::IsSecurityWrapper(obj))
{
obj = XPCWrapper::Unwrap(cx, obj);
if(!obj)
return xpc_qsThrow(cx, NS_ERROR_XPC_SECURITY_MANAGER_VETO);
}
JSObject *cur = obj;
XPCWrappedNativeTearOff *tearoff;
XPCWrappedNative *wrapper =
@ -927,9 +934,17 @@ xpc_qsUnwrapArgImpl(JSContext *cx,
return NS_OK;
}
JSObject *inner = nsnull;
if(XPCWrapper::IsSecurityWrapper(src))
{
inner = XPCWrapper::Unwrap(cx, src);
if(!inner)
return NS_ERROR_XPC_SECURITY_MANAGER_VETO;
}
// From XPCConvert::JSObject2NativeInterface
XPCWrappedNative* wrappedNative =
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, src);
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, inner ? inner : src);
nsISupports *iface;
if(wrappedNative)
{
@ -951,21 +966,6 @@ xpc_qsUnwrapArgImpl(JSContext *cx,
return NS_ERROR_XPC_BAD_CONVERT_JS;
}
// Does the JSObject have 'nsISupportness'?
// XXX hmm, I wonder if this matters anymore with no
// oldstyle DOM objects around.
if(XPCConvert::GetISupportsFromJSObject(src, &iface))
{
if(!iface || NS_FAILED(iface->QueryInterface(iid, ppArg)))
{
*ppArgRef = nsnull;
return NS_ERROR_XPC_BAD_CONVERT_JS;
}
*ppArgRef = static_cast<nsISupports*>(*ppArg);
return NS_OK;
}
// Create the ccx needed for quick stubs.
XPCCallContext ccx(JS_CALLER, cx);
if(!ccx.IsValid())

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

@ -64,6 +64,7 @@ _TEST_FILES = bug500931_helper.html \
test_bug500691.html \
test_bug502959.html \
test_bug503926.html \
test_bug505915.html \
test_bug517163.html \
$(NULL)

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

@ -0,0 +1,65 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=505915
-->
<head>
<title>Test for Bug 505915</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=505915">Mozilla Bug 505915</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 505915 **/
function go() {
var ifr = $('ifr');
try {
document.documentElement.appendChild(ifr.contentWindow);
ok(false, "weird behavior");
} catch (e) {
ok(/NS_ERROR_XPC_SECURITY_MANAGER_VETO/.test(e),
"threw a security exception instead of an invalid child exception");
}
try {
document.createTreeWalker(ifr.contentDocument, 0, null, false);
ok(false, "should have thrown a security exception");
} catch (e) {
ok(/NS_ERROR_XPC_SECURITY_MANAGER_VETO/.test(e),
"threw a security exception instead of an invalid child exception");
}
var xhr = new XMLHttpRequest();
var orsc = new XPCSafeJSObjectWrapper(function(){});
xhr.onreadystatechange = orsc;
// we only can test that the above didn't throw (which it shouldn't).
try {
xhr.onreadystatechange = ifr.contentWindow;
ok(false, "weird behavior");
} catch (e) {
ok(/NS_ERROR_XPC_SECURITY_MANAGER_VETO/.test(e),
"threw a security exception instead of an invalid child exception");
}
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
<iframe id="ifr" onload="go()" src="http://example.org/"></iframe>
</body>
</html>