mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 666604 - Allow untrusted events to trigger a link, r=bz
--HG-- extra : rebase_source : e0b8510a039425c17a3d412241aa8f24df05558a
This commit is contained in:
parent
48d3be6b3d
commit
e5f1a50b21
@ -1316,10 +1316,13 @@ public:
|
||||
* @param aIsUserTriggered whether the user triggered the link. This would be
|
||||
* false for loads from auto XLinks or from the
|
||||
* click() method if we ever implement it.
|
||||
* @param aIsTrusted If PR_FALSE, JS Context will be pushed to stack
|
||||
* when the link is triggered.
|
||||
*/
|
||||
static void TriggerLink(nsIContent *aContent, nsPresContext *aPresContext,
|
||||
nsIURI *aLinkURI, const nsString& aTargetSpec,
|
||||
PRBool aClick, PRBool aIsUserTriggered);
|
||||
PRBool aClick, PRBool aIsUserTriggered,
|
||||
PRBool aIsTrusted);
|
||||
|
||||
/**
|
||||
* Return top-level widget in the parent chain.
|
||||
|
@ -4076,7 +4076,8 @@ nsContentUtils::IsSystemPrincipal(nsIPrincipal* aPrincipal)
|
||||
void
|
||||
nsContentUtils::TriggerLink(nsIContent *aContent, nsPresContext *aPresContext,
|
||||
nsIURI *aLinkURI, const nsString &aTargetSpec,
|
||||
PRBool aClick, PRBool aIsUserTriggered)
|
||||
PRBool aClick, PRBool aIsUserTriggered,
|
||||
PRBool aIsTrusted)
|
||||
{
|
||||
NS_ASSERTION(aPresContext, "Need a nsPresContext");
|
||||
NS_PRECONDITION(aLinkURI, "No link URI");
|
||||
@ -4111,7 +4112,8 @@ nsContentUtils::TriggerLink(nsIContent *aContent, nsPresContext *aPresContext,
|
||||
|
||||
// Only pass off the click event if the script security manager says it's ok.
|
||||
if (NS_SUCCEEDED(proceed)) {
|
||||
handler->OnLinkClick(aContent, aLinkURI, aTargetSpec.get());
|
||||
handler->OnLinkClick(aContent, aLinkURI, aTargetSpec.get(), nsnull, nsnull,
|
||||
aIsTrusted);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5032,7 +5032,10 @@ nsGenericElement::CheckHandleEventForLinksPrecondition(nsEventChainVisitor& aVis
|
||||
nsIURI** aURI) const
|
||||
{
|
||||
if (aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault ||
|
||||
!NS_IS_TRUSTED_EVENT(aVisitor.mEvent) ||
|
||||
(!NS_IS_TRUSTED_EVENT(aVisitor.mEvent) &&
|
||||
(aVisitor.mEvent->message != NS_MOUSE_CLICK) &&
|
||||
(aVisitor.mEvent->message != NS_KEY_PRESS) &&
|
||||
(aVisitor.mEvent->message != NS_UI_ACTIVATE)) ||
|
||||
!aVisitor.mPresContext ||
|
||||
(aVisitor.mEvent->flags & NS_EVENT_FLAG_PREVENT_ANCHOR_ACTIONS)) {
|
||||
return PR_FALSE;
|
||||
@ -5078,7 +5081,7 @@ nsGenericElement::PreHandleEventForLinks(nsEventChainPreVisitor& aVisitor)
|
||||
nsAutoString target;
|
||||
GetLinkTarget(target);
|
||||
nsContentUtils::TriggerLink(this, aVisitor.mPresContext, absURI, target,
|
||||
PR_FALSE, PR_TRUE);
|
||||
PR_FALSE, PR_TRUE, PR_TRUE);
|
||||
// Make sure any ancestor links don't also TriggerLink
|
||||
aVisitor.mEvent->flags |= NS_EVENT_FLAG_PREVENT_ANCHOR_ACTIONS;
|
||||
}
|
||||
@ -5181,7 +5184,7 @@ nsGenericElement::PostHandleEventForLinks(nsEventChainPostVisitor& aVisitor)
|
||||
nsAutoString target;
|
||||
GetLinkTarget(target);
|
||||
nsContentUtils::TriggerLink(this, aVisitor.mPresContext, absURI, target,
|
||||
PR_TRUE, PR_TRUE);
|
||||
PR_TRUE, PR_TRUE, NS_IS_TRUSTED_EVENT(aVisitor.mEvent));
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
}
|
||||
|
@ -502,6 +502,7 @@ _TEST_FILES2 = \
|
||||
somedatas.resource \
|
||||
somedatas.resource^headers^ \
|
||||
delayedServerEvents.sjs \
|
||||
test_bug666604.html \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
|
125
content/base/test/test_bug666604.html
Normal file
125
content/base/test/test_bug666604.html
Normal file
@ -0,0 +1,125 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=666604
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 666604</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=666604">Mozilla Bug 666604</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<a href="javascript:activationListener()" id="testlink">test</a>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 666604 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var activationListener;
|
||||
|
||||
function dispatchClick(target, ctrl) {
|
||||
var e = document.createEvent("MouseEvent");
|
||||
e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0,
|
||||
ctrl, false, false, false, 0, null);
|
||||
target.dispatchEvent(e);
|
||||
}
|
||||
|
||||
function dispatchReturn(target, ctrl) {
|
||||
var e = document.createEvent("KeyboardEvent");
|
||||
e.initKeyEvent("keypress", true, true, window, ctrl, false,
|
||||
false, false, 13, 0);
|
||||
target.dispatchEvent(e);
|
||||
}
|
||||
|
||||
function dispatchDOMActivate(target) {
|
||||
var e = document.createEvent("UIEvent");
|
||||
e.initUIEvent("DOMActivate", true, true, window, 0);
|
||||
target.dispatchEvent(e);
|
||||
}
|
||||
|
||||
var testlink = document.getElementById("testlink");
|
||||
function test1() {
|
||||
activationListener =
|
||||
function() {
|
||||
ok(true, "Untrusted click should activate a link");
|
||||
test2();
|
||||
}
|
||||
dispatchClick(testlink, false);
|
||||
}
|
||||
|
||||
function test2() {
|
||||
activationListener =
|
||||
function() {
|
||||
ok(true, "Untrusted return keypress should activate a link");
|
||||
test3();
|
||||
}
|
||||
dispatchReturn(testlink, false);
|
||||
}
|
||||
|
||||
function test3() {
|
||||
activationListener =
|
||||
function() {
|
||||
ok(false, "Untrusted click+ctrl should not activate a link");
|
||||
test4();
|
||||
}
|
||||
dispatchClick(testlink, true);
|
||||
setTimeout(test4, 1000);
|
||||
}
|
||||
|
||||
function test4() {
|
||||
activationListener =
|
||||
function() {
|
||||
ok(false, "Untrusted return keypress+ctrl should not activate a link");
|
||||
test5();
|
||||
}
|
||||
dispatchReturn(testlink, true);
|
||||
setTimeout(test5, 1000);
|
||||
}
|
||||
|
||||
function test5() {
|
||||
activationListener =
|
||||
function() {
|
||||
ok(true, "click() should activate a link");
|
||||
test6();
|
||||
}
|
||||
testlink.click();
|
||||
}
|
||||
|
||||
function test6() {
|
||||
activationListener =
|
||||
function() {
|
||||
ok(true, "Untrusted DOMActivate should activate a link");
|
||||
test7();
|
||||
}
|
||||
dispatchDOMActivate(testlink);
|
||||
}
|
||||
|
||||
function test7() {
|
||||
testlink.href = "javascript:opener.activationListener(); window.close();";
|
||||
testlink.target = "_blank";
|
||||
activationListener =
|
||||
function() {
|
||||
ok(true, "Click() should activate a link");
|
||||
setTimeout(test9, 0);
|
||||
}
|
||||
testlink.click();
|
||||
}
|
||||
|
||||
function test9() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
addLoadEvent(test1);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -11468,17 +11468,21 @@ public:
|
||||
OnLinkClickEvent(nsDocShell* aHandler, nsIContent* aContent,
|
||||
nsIURI* aURI,
|
||||
const PRUnichar* aTargetSpec,
|
||||
nsIInputStream* aPostDataStream = 0,
|
||||
nsIInputStream* aHeadersDataStream = 0);
|
||||
nsIInputStream* aPostDataStream,
|
||||
nsIInputStream* aHeadersDataStream,
|
||||
PRBool aIsTrusted);
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(mHandler->mScriptGlobal));
|
||||
nsAutoPopupStatePusher popupStatePusher(window, mPopupState);
|
||||
|
||||
mHandler->OnLinkClickSync(mContent, mURI,
|
||||
mTargetSpec.get(), mPostDataStream,
|
||||
mHeadersDataStream,
|
||||
nsnull, nsnull);
|
||||
nsCxPusher pusher;
|
||||
if (mIsTrusted || pusher.Push(mContent)) {
|
||||
mHandler->OnLinkClickSync(mContent, mURI,
|
||||
mTargetSpec.get(), mPostDataStream,
|
||||
mHeadersDataStream,
|
||||
nsnull, nsnull);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -11490,6 +11494,7 @@ private:
|
||||
nsCOMPtr<nsIInputStream> mHeadersDataStream;
|
||||
nsCOMPtr<nsIContent> mContent;
|
||||
PopupControlState mPopupState;
|
||||
PRBool mIsTrusted;
|
||||
};
|
||||
|
||||
OnLinkClickEvent::OnLinkClickEvent(nsDocShell* aHandler,
|
||||
@ -11497,13 +11502,15 @@ OnLinkClickEvent::OnLinkClickEvent(nsDocShell* aHandler,
|
||||
nsIURI* aURI,
|
||||
const PRUnichar* aTargetSpec,
|
||||
nsIInputStream* aPostDataStream,
|
||||
nsIInputStream* aHeadersDataStream)
|
||||
nsIInputStream* aHeadersDataStream,
|
||||
PRBool aIsTrusted)
|
||||
: mHandler(aHandler)
|
||||
, mURI(aURI)
|
||||
, mTargetSpec(aTargetSpec)
|
||||
, mPostDataStream(aPostDataStream)
|
||||
, mHeadersDataStream(aHeadersDataStream)
|
||||
, mContent(aContent)
|
||||
, mIsTrusted(aIsTrusted)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(mHandler->mScriptGlobal));
|
||||
|
||||
@ -11517,7 +11524,8 @@ nsDocShell::OnLinkClick(nsIContent* aContent,
|
||||
nsIURI* aURI,
|
||||
const PRUnichar* aTargetSpec,
|
||||
nsIInputStream* aPostDataStream,
|
||||
nsIInputStream* aHeadersDataStream)
|
||||
nsIInputStream* aHeadersDataStream,
|
||||
PRBool aIsTrusted)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "wrong thread");
|
||||
|
||||
@ -11545,7 +11553,7 @@ nsDocShell::OnLinkClick(nsIContent* aContent,
|
||||
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new OnLinkClickEvent(this, aContent, aURI, target.get(),
|
||||
aPostDataStream, aHeadersDataStream);
|
||||
aPostDataStream, aHeadersDataStream, aIsTrusted);
|
||||
return NS_DispatchToCurrentThread(ev);
|
||||
}
|
||||
|
||||
|
@ -234,8 +234,9 @@ public:
|
||||
NS_IMETHOD OnLinkClick(nsIContent* aContent,
|
||||
nsIURI* aURI,
|
||||
const PRUnichar* aTargetSpec,
|
||||
nsIInputStream* aPostDataStream = 0,
|
||||
nsIInputStream* aHeadersDataStream = 0);
|
||||
nsIInputStream* aPostDataStream,
|
||||
nsIInputStream* aHeadersDataStream,
|
||||
PRBool aIsTrusted);
|
||||
NS_IMETHOD OnLinkClickSync(nsIContent* aContent,
|
||||
nsIURI* aURI,
|
||||
const PRUnichar* aTargetSpec,
|
||||
|
@ -48,7 +48,8 @@ class nsGUIEvent;
|
||||
|
||||
// Interface ID for nsILinkHandler
|
||||
#define NS_ILINKHANDLER_IID \
|
||||
{ 0x71627c30, 0xd3c5, 0x4ad0,{0xb5, 0x33, 0x6e, 0x01, 0x91, 0xf2, 0x79, 0x32}}
|
||||
{ 0xd85670a1, 0x224a, 0x4562, \
|
||||
{ 0x87, 0xa9, 0x43, 0xa5, 0x24, 0xe7, 0xd0, 0x1b } }
|
||||
|
||||
/**
|
||||
* Interface used for handling clicks on links
|
||||
@ -66,12 +67,14 @@ public:
|
||||
* string)
|
||||
* @param aPostDataStream the POST data to send
|
||||
* @param aHeadersDataStream ???
|
||||
* @param aIsTrusted PR_FALSE if the triggerer is an untrusted DOM event.
|
||||
*/
|
||||
NS_IMETHOD OnLinkClick(nsIContent* aContent,
|
||||
nsIURI* aURI,
|
||||
const PRUnichar* aTargetSpec,
|
||||
nsIInputStream* aPostDataStream = 0,
|
||||
nsIInputStream* aHeadersDataStream = 0) = 0;
|
||||
nsIInputStream* aPostDataStream,
|
||||
nsIInputStream* aHeadersDataStream,
|
||||
PRBool aIsTrusted) = 0;
|
||||
|
||||
/**
|
||||
* Process a click on a link.
|
||||
|
@ -532,7 +532,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetURL(const char *aURL,
|
||||
nsAutoPopupStatePusher popupStatePusher((PopupControlState)blockPopups);
|
||||
|
||||
rv = lh->OnLinkClick(mContent, uri, unitarget.get(),
|
||||
aPostStream, headersDataStream);
|
||||
aPostStream, headersDataStream, PR_TRUE);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ nsIsIndexFrame::OnSubmit(nsPresContext* aPresContext)
|
||||
|
||||
// Now pretend we're triggering a link
|
||||
nsContentUtils::TriggerLink(mContent, aPresContext, uri,
|
||||
EmptyString(), PR_TRUE, PR_TRUE);
|
||||
EmptyString(), PR_TRUE, PR_TRUE, PR_TRUE);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1627,7 +1627,7 @@ nsImageFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
clicked = PR_TRUE;
|
||||
}
|
||||
nsContentUtils::TriggerLink(anchorNode, aPresContext, uri, target,
|
||||
clicked, PR_TRUE);
|
||||
clicked, PR_TRUE, PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user