зеркало из https://github.com/mozilla/gecko-dev.git
Bug 612267 - window.__proto__ doesn't correspond to Window.prototype. r=jst
This commit is contained in:
Родитель
b57d7c1002
Коммит
297a205814
|
@ -2548,37 +2548,14 @@ nsJSContext::ConnectToInner(nsIScriptGlobalObject *aNewInner, void *aOuterGlobal
|
|||
JSObject *newInnerJSObject = (JSObject *)aNewInner->GetScriptGlobal(JAVASCRIPT);
|
||||
JSObject *outerGlobal = (JSObject *)aOuterGlobal;
|
||||
|
||||
// Make the inner and outer window both share the same
|
||||
// prototype. The prototype we share is the outer window's
|
||||
// prototype, this way XPConnect can still find the wrapper to
|
||||
// use when making a call like alert() (w/o qualifying it with
|
||||
// "window."). XPConnect looks up the wrapper based on the
|
||||
// function object's parent, which is the object the function
|
||||
// was called on, and when calling alert() we'll be calling the
|
||||
// alert() function from the outer window's prototype off of the
|
||||
// inner window. In this case XPConnect is able to find the
|
||||
// outer (through the JSExtendedClass hook outerObject), so this
|
||||
// prototype sharing works.
|
||||
|
||||
// Now that we're connecting the outer global to the inner one,
|
||||
// we must have transplanted it. The JS engine tries to maintain
|
||||
// the global object's compartment as its default compartment,
|
||||
// so update that now since it might have changed.
|
||||
JS_SetGlobalObject(mContext, outerGlobal);
|
||||
|
||||
// We do *not* want to use anything else out of the outer
|
||||
// object's prototype chain than the first prototype, which is
|
||||
// the XPConnect prototype. The rest we want from the inner
|
||||
// window's prototype, i.e. the global scope polluter and
|
||||
// Object.prototype. This way the outer also gets the benefits
|
||||
// of the global scope polluter, and the inner window's
|
||||
// Object.prototype.
|
||||
JSObject *proto = JS_GetPrototype(mContext, outerGlobal);
|
||||
JSObject *innerProto = JS_GetPrototype(mContext, newInnerJSObject);
|
||||
JSObject *innerProtoProto = JS_GetPrototype(mContext, innerProto);
|
||||
|
||||
JS_SetPrototype(mContext, newInnerJSObject, proto);
|
||||
JS_SetPrototype(mContext, proto, innerProtoProto);
|
||||
NS_ASSERTION(JS_GetPrototype(mContext, outerGlobal) ==
|
||||
JS_GetPrototype(mContext, newInnerJSObject),
|
||||
"outer and inner globals should have the same prototype");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2626,19 +2603,6 @@ nsJSContext::CreateOuterObject(nsIScriptGlobalObject *aGlobalObject,
|
|||
JS_SetOptions(mContext, JS_GetOptions(mContext) | JSOPTION_XML);
|
||||
}
|
||||
|
||||
nsIXPConnect *xpc = nsContentUtils::XPConnect();
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
||||
|
||||
nsresult rv = xpc->WrapNative(mContext, aCurrentInner->GetGlobalJSObject(),
|
||||
aCurrentInner, NS_GET_IID(nsISupports),
|
||||
getter_AddRefs(holder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIXPConnectWrappedNative> wrapper(do_QueryInterface(holder));
|
||||
NS_ABORT_IF_FALSE(wrapper, "bad wrapper");
|
||||
|
||||
wrapper->RefreshPrototype();
|
||||
|
||||
JSObject *outer =
|
||||
NS_NewOuterWindowProxy(mContext, aCurrentInner->GetGlobalJSObject());
|
||||
if (!outer) {
|
||||
|
@ -2655,6 +2619,20 @@ nsJSContext::SetOuterObject(void *aOuterObject)
|
|||
|
||||
// Force our context's global object to be the outer.
|
||||
JS_SetGlobalObject(mContext, outer);
|
||||
|
||||
// NB: JS_SetGlobalObject sets mContext->compartment.
|
||||
JSObject *inner = JS_GetParent(mContext, outer);
|
||||
|
||||
nsIXPConnect *xpc = nsContentUtils::XPConnect();
|
||||
nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
|
||||
nsresult rv = xpc->GetWrappedNativeOfJSObject(mContext, inner,
|
||||
getter_AddRefs(wrapper));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ABORT_IF_FALSE(wrapper, "bad wrapper");
|
||||
|
||||
wrapper->RefreshPrototype();
|
||||
JS_SetPrototype(mContext, outer, JS_GetPrototype(mContext, inner));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@ _TEST_FILES = \
|
|||
test_bug369306.html \
|
||||
test_bug61098.html \
|
||||
test_bug597809.html \
|
||||
test_bug612267.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=612267
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 393974</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/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=612267">Mozilla Bug 612267</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
Window.prototype.test = 'PASS';
|
||||
is(window.test, 'PASS', "setting Window.prototype affects window.__proto__");
|
||||
is(test, 'PASS', "setting Window.prototype affects the inner window lookup for sure");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -1148,7 +1148,7 @@ nsXPConnect::InitClassesWithNewWrappedGlobal(JSContext * aJSContext,
|
|||
return UnexpectedFailure(NS_ERROR_FAILURE);
|
||||
|
||||
// Note: This call cooperates with a call to wrapper->RefreshPrototype()
|
||||
// in nsJSEnvironment::CreateOuterObject in order to ensure that the
|
||||
// in nsJSEnvironment::SetOuterObject in order to ensure that the
|
||||
// prototype defines its constructor on the right global object.
|
||||
if(wrapper->GetProto()->GetScriptableInfo())
|
||||
scope->RemoveWrappedNativeProtos();
|
||||
|
|
Загрузка…
Ссылка в новой задаче