зеркало из https://github.com/mozilla/gecko-dev.git
Bug 533596 - Implement XPCNativeWrapper.unwrap. r=peterv sr=jst
This commit is contained in:
Родитель
eee412ce5e
Коммит
5e6b899dc8
|
@ -866,11 +866,7 @@ nsDOMWindowUtils::GetCOWForObject()
|
|||
|| !hasCap)
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIXPConnect> xpc = do_GetService("@mozilla.org/js/xpc/XPConnect;1",
|
||||
&rv);
|
||||
if (NS_FAILED(rv))
|
||||
return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIXPConnect> xpc = nsContentUtils::XPConnect();
|
||||
|
||||
// get the xpconnect native call context
|
||||
nsAXPCNativeCallContext *cc = nsnull;
|
||||
|
@ -880,7 +876,7 @@ nsDOMWindowUtils::GetCOWForObject()
|
|||
|
||||
// Get JSContext of current call
|
||||
JSContext* cx;
|
||||
rv = cc->GetJSContext(&cx);
|
||||
nsresult rv = cc->GetJSContext(&cx);
|
||||
if(NS_FAILED(rv) || !cx)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -949,3 +945,44 @@ nsDOMWindowUtils::DispatchDOMEventViaPresShell(nsIDOMNode* aTarget,
|
|||
*aRetVal = (status != nsEventStatus_eConsumeNoDefault);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::GetClassName(char **aName)
|
||||
{
|
||||
if (!nsContentUtils::IsCallerTrustedForRead()) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
// get the xpconnect native call context
|
||||
nsAXPCNativeCallContext *cc = nsnull;
|
||||
nsContentUtils::XPConnect()->GetCurrentNativeCallContext(&cc);
|
||||
if(!cc)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Get JSContext of current call
|
||||
JSContext* cx;
|
||||
nsresult rv = cc->GetJSContext(&cx);
|
||||
if(NS_FAILED(rv) || !cx)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// get argc and argv and verify arg count
|
||||
PRUint32 argc;
|
||||
rv = cc->GetArgc(&argc);
|
||||
if(NS_FAILED(rv))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if(argc < 1)
|
||||
return NS_ERROR_XPC_NOT_ENOUGH_ARGS;
|
||||
|
||||
jsval* argv;
|
||||
rv = cc->GetArgvPtr(&argv);
|
||||
if(NS_FAILED(rv) || !argv)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Our argument must be a non-null object.
|
||||
if(JSVAL_IS_PRIMITIVE(argv[0]))
|
||||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
|
||||
*aName = NS_strdup(JS_GET_CLASS(cx, JSVAL_TO_OBJECT(argv[0]))->name);
|
||||
return *aName ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ interface nsIDOMElement;
|
|||
interface nsIDOMHTMLCanvasElement;
|
||||
interface nsIDOMEvent;
|
||||
|
||||
[scriptable, uuid(4775e623-d596-4364-8637-0968a5ce5e3d)]
|
||||
[scriptable, uuid(0e13d9a6-bcd1-4d61-9986-c32f78f99d1a)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
|
@ -421,4 +421,10 @@ interface nsIDOMWindowUtils : nsISupports {
|
|||
boolean dispatchDOMEventViaPresShell(in nsIDOMNode aTarget,
|
||||
in nsIDOMEvent aEvent,
|
||||
in boolean aTrusted);
|
||||
|
||||
/**
|
||||
* Returns the real classname (possibly of the mostly-transparent security
|
||||
* wrapper) of aObj.
|
||||
*/
|
||||
string getClassName(/*in JSObjectPtr aObj*/);
|
||||
};
|
||||
|
|
|
@ -561,6 +561,31 @@ XPC_NW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
return RewrapIfDeepWrapper(cx, obj, v, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
GetwrappedJSObject(JSContext *cx, JSObject *obj, jsval *vp)
|
||||
{
|
||||
// If we're wrapping an untrusted content wrapper, then we should
|
||||
// return a safe wrapper for the underlying native object. Otherwise,
|
||||
// such a wrapper would be superfluous.
|
||||
|
||||
nsIScriptSecurityManager *ssm = GetSecurityManager();
|
||||
nsCOMPtr<nsIPrincipal> prin;
|
||||
nsresult rv = ssm->GetObjectPrincipal(cx, obj, getter_AddRefs(prin));
|
||||
if (NS_FAILED(rv)) {
|
||||
return ThrowException(rv, cx);
|
||||
}
|
||||
|
||||
jsval v = OBJECT_TO_JSVAL(obj);
|
||||
|
||||
PRBool isSystem;
|
||||
if (NS_SUCCEEDED(ssm->IsSystemPrincipal(prin, &isSystem)) && isSystem) {
|
||||
*vp = v;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
return XPCSafeJSObjectWrapper::WrapObject(cx, JS_GetScopeChain(cx), v, vp);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
XPC_NW_GetOrSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
|
||||
JSBool aIsSet)
|
||||
|
@ -611,27 +636,7 @@ XPC_NW_GetOrSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
|
|||
|
||||
if (!aIsSet &&
|
||||
id == GetRTStringByIndex(cx, XPCJSRuntime::IDX_WRAPPED_JSOBJECT)) {
|
||||
// If we're wrapping an untrusted content wrapper, then we should
|
||||
// return a safe wrapper for the underlying native object. Otherwise,
|
||||
// such a wrapper would be superfluous.
|
||||
|
||||
jsval nativeVal = OBJECT_TO_JSVAL(nativeObj);
|
||||
|
||||
nsIScriptSecurityManager *ssm = GetSecurityManager();
|
||||
nsCOMPtr<nsIPrincipal> prin;
|
||||
nsresult rv = ssm->GetObjectPrincipal(cx, nativeObj,
|
||||
getter_AddRefs(prin));
|
||||
if (NS_FAILED(rv)) {
|
||||
return ThrowException(rv, cx);
|
||||
}
|
||||
|
||||
PRBool isSystem;
|
||||
if (NS_SUCCEEDED(ssm->IsSystemPrincipal(prin, &isSystem)) && isSystem) {
|
||||
*vp = nativeVal;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
return XPCSafeJSObjectWrapper::WrapObject(cx, nsnull, nativeVal, vp);
|
||||
return GetwrappedJSObject(cx, nativeObj, vp);
|
||||
}
|
||||
|
||||
return GetOrSetNativeProperty(cx, obj, wrappedNative, id, vp, aIsSet,
|
||||
|
@ -1158,6 +1163,31 @@ XPC_NW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
return NativeToString(cx, wrappedNative, argc, argv, rval, JS_TRUE);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
UnwrapNW(JSContext *cx, uintN argc, jsval *vp)
|
||||
{
|
||||
if (argc != 1) {
|
||||
return ThrowException(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx);
|
||||
}
|
||||
|
||||
jsval v = JS_ARGV(cx, vp)[0];
|
||||
if (JSVAL_IS_PRIMITIVE(v)) {
|
||||
return ThrowException(NS_ERROR_INVALID_ARG, cx);
|
||||
}
|
||||
|
||||
if (!IsNativeWrapper(JSVAL_TO_OBJECT(v))) {
|
||||
JS_SET_RVAL(cx, vp, v);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
return GetwrappedJSObject(cx, JSVAL_TO_OBJECT(v), vp);
|
||||
}
|
||||
|
||||
static JSFunctionSpec static_functions[] = {
|
||||
JS_FN("unwrap", UnwrapNW, 1, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
// static
|
||||
PRBool
|
||||
XPCNativeWrapper::AttachNewConstructorObject(XPCCallContext &ccx,
|
||||
|
@ -1166,7 +1196,7 @@ XPCNativeWrapper::AttachNewConstructorObject(XPCCallContext &ccx,
|
|||
JSObject *class_obj =
|
||||
::JS_InitClass(ccx, aGlobalObject, nsnull, &internal::NWClass.base,
|
||||
XPCNativeWrapperCtor, 0, nsnull, nsnull,
|
||||
nsnull, nsnull);
|
||||
nsnull, static_functions);
|
||||
if (!class_obj) {
|
||||
NS_WARNING("can't initialize the XPCNativeWrapper class");
|
||||
return PR_FALSE;
|
||||
|
|
|
@ -47,6 +47,7 @@ _CHROME_FILES = \
|
|||
test_bug500931.xul \
|
||||
bug503926.xul \
|
||||
test_bug503926.xul \
|
||||
test_bug533596.xul \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_CHROME_FILES)
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=500931
|
||||
-->
|
||||
<window title="Mozilla Bug 500931"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=533596"
|
||||
target="_blank">Mozilla Bug 533596</a>
|
||||
</body>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
|
||||
/** Test for Bug 533596 **/
|
||||
|
||||
function go() {
|
||||
try { XPCNativeWrapper.unwrap(); } catch (e) {}
|
||||
try { XPCNativeWrapper.unwrap(0); } catch (e) {}
|
||||
try { XPCNativeWrapper.unwrap(null); } catch (e) {}
|
||||
|
||||
var o = {};
|
||||
is(o, XPCNativeWrapper.unwrap(o), "unwrap on a random object returns it");
|
||||
|
||||
var win = $('ifr').contentWindow;
|
||||
var utils = window.getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
is(utils.getClassName(win), "XPCNativeWrapper", "win is an XPCNW");
|
||||
is(utils.getClassName(XPCNativeWrapper.unwrap(win)), "XPCSafeJSObjectWrapper",
|
||||
"unwrap on an NW returns the same object");
|
||||
is(utils.getClassName(XPCNativeWrapper.unwrap(new XPCNativeWrapper(win))), "XPCSafeJSObjectWrapper",
|
||||
"unwrap on an explicit NW works too");
|
||||
|
||||
ok(utils.getClassName(window) !== "XPCNativeWrapper", "window is not a native wrapper");
|
||||
ok(utils.getClassName(XPCNativeWrapper.unwrap(new XPCNativeWrapper(window))) !== "XPCSafeJSObjectWrapper",
|
||||
"unwrapping a chrome object returns the object itself");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
]]></script>
|
||||
<iframe type="content"
|
||||
src="http://example.org/tests/js/src/xpconnect/tests/mochitest/bug500931_helper.html"
|
||||
onload="go()"
|
||||
id="ifr">
|
||||
</iframe>
|
||||
</window>
|
Загрузка…
Ссылка в новой задаче