Bug 650273 - Force a frame here. r=luke

--HG--
extra : rebase_source : eba79b2d20d380c7172bb982c09523c3df180185
This commit is contained in:
Blake Kaplan 2011-05-02 15:47:10 -07:00
Родитель f0838a7d54
Коммит ccf4d72d2d
6 изменённых файлов: 114 добавлений и 4 удалений

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

@ -88,6 +88,7 @@
#include "xpcpublic.h"
#include "jsdbgapi.h" // for JS_ClearWatchPointsForObject
#include "jswrapper.h"
#include "jsxdrapi.h"
#include "nsIArray.h"
#include "nsIObjectInputStream.h"
@ -1881,7 +1882,9 @@ nsJSContext::CallEventHandler(nsISupports* aTarget, void *aScope, void *aHandler
jsval funval = OBJECT_TO_JSVAL(funobj);
JSAutoEnterCompartment ac;
if (!ac.enter(mContext, funobj) || !JS_WrapObject(mContext, &target)) {
js::ForceFrame ff(mContext, funobj);
if (!ac.enter(mContext, funobj) || !ff.enter() ||
!JS_WrapObject(mContext, &target)) {
sSecurityManager->PopContextPrincipal(mContext);
return NS_ERROR_FAILURE;
}

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

@ -357,12 +357,30 @@ TransparentObjectWrapper(JSContext *cx, JSObject *obj, JSObject *wrappedProto, J
}
ForceFrame::ForceFrame(JSContext *cx, JSObject *target)
: context(cx),
target(target)
{
}
bool
ForceFrame::enter()
{
LeaveTrace(context);
JS_ASSERT(context->compartment == target->compartment());
JSObject *scopeChain = target->getGlobal();
JS_ASSERT(scopeChain->isNative());
return context->stack.pushDummyFrame(context, *scopeChain, &frame);
}
AutoCompartment::AutoCompartment(JSContext *cx, JSObject *target)
: context(cx),
origin(cx->compartment),
target(target),
destination(target->getCompartment()),
input(cx),
entered(false)
{
}

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

@ -156,6 +156,21 @@ class JS_FRIEND_API(JSCrossCompartmentWrapper) : public JSWrapper {
namespace js {
// A hacky class that lets a friend force a fake frame. We must already be
// in the compartment of |target| when we enter the forced frame.
class JS_FRIEND_API(ForceFrame)
{
public:
JSContext * const context;
JSObject * const target;
private:
DummyFrameGuard frame;
public:
ForceFrame(JSContext *cx, JSObject *target);
bool enter();
};
class AutoCompartment
{
public:
@ -165,8 +180,6 @@ class AutoCompartment
JSCompartment * const destination;
private:
Maybe<DummyFrameGuard> frame;
FrameRegs regs;
AutoStringRooter input;
bool entered;
public:

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

@ -89,6 +89,8 @@ _TEST_FILES = bug500931_helper.html \
test2_bug629331.html \
test_bug618017.html \
test_bug636097.html \
test_bug650273.html \
file_bug650273.html \
$(NULL)
#test_bug484107.html \

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

@ -0,0 +1,31 @@
<!-- test by moz_bug_r_a4@yahoo.com -->
<body onload="a()">
<script>
var targetUrl = "http://example.com/";
var l;
function a() {
var o = {};
o.toString = function() {
l();
return "a";
};
var f = Components.lookupMethod(document, "title");
setTimeout(f, 0, o);
}
function l() {
var l = false;
onunload = function() {
l = true;
};
location = targetUrl;
do {
var r = new XMLHttpRequest();
r.open("GET", location.href, false);
r.overrideMimeType("text/plain");
try { r.send(null); }
catch (e) {}
} while (!l);
}
</script>

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

@ -0,0 +1,43 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=650273
test by moz_bug_r_a4@yahoo.com
-->
<head>
<title>Test for Bug 650273</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=650273">Mozilla Bug 650273</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 count = 0;
function done() {
if (++count == 2) {
try {
ok($('ifr').location.host === 'example.com', "shouldn't see this");
} catch (e) {
ok(true, "navigation successfully happened");
}
SimpleTest.finish();
}
}
</script>
<iframe id="ifr" src="file_bug650273.html" onload="done()"></iframe>
</pre>
</body>
</html>