diff --git a/mozilla/content/html/content/src/nsHTMLFormElement.cpp b/mozilla/content/html/content/src/nsHTMLFormElement.cpp
index 05706e9a08a..4512764c6fb 100644
--- a/mozilla/content/html/content/src/nsHTMLFormElement.cpp
+++ b/mozilla/content/html/content/src/nsHTMLFormElement.cpp
@@ -726,7 +726,7 @@ nsHTMLFormElement::HandleDOMEvent(nsIPresContext* aPresContext,
// to forget it and the form element will build a new one
ForgetPendingSubmission();
}
- rv = DoSubmitOrReset(aPresContext, aEvent, aEvent->message);
+ DoSubmitOrReset(aPresContext, aEvent, aEvent->message);
}
break;
}
@@ -833,9 +833,7 @@ nsHTMLFormElement::DoSubmit(nsIPresContext* aPresContext, nsEvent* aEvent)
//
// perform the submission
//
- SubmitSubmission(aPresContext, submission);
-
- return NS_OK;
+ return SubmitSubmission(aPresContext, submission);
}
nsresult
diff --git a/mozilla/docshell/base/nsDocShell.cpp b/mozilla/docshell/base/nsDocShell.cpp
index ae57becd3c6..2904c7c7304 100644
--- a/mozilla/docshell/base/nsDocShell.cpp
+++ b/mozilla/docshell/base/nsDocShell.cpp
@@ -73,6 +73,8 @@
#include "nsIUploadChannel.h"
#include "nsISecurityEventSink.h"
#include "nsIScriptSecurityManager.h"
+#include "nsIJSContextStack.h"
+#include "nsIScriptObjectPrincipal.h"
#include "nsDocumentCharsetInfoCID.h"
#include "nsICanvasFrame.h"
#include "nsContentPolicyUtils.h" // NS_CheckContentLoadPolicy(...)
@@ -4937,6 +4939,135 @@ nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer)
}
+nsresult
+nsDocShell::CheckLoadingPermissions(nsISupports *aOwner)
+{
+ nsresult rv = NS_OK;
+
+ if (mPrefs) {
+ PRBool frameLoadCheckDisabled = PR_FALSE;
+ rv = mPrefs->GetBoolPref("docshell.frameloadcheck.disabled",
+ &frameLoadCheckDisabled);
+
+ if (NS_SUCCEEDED(rv) && frameLoadCheckDisabled) {
+ return rv;
+ }
+ }
+
+ // Check to see if we're a frame in a frameset frame, or iframe,
+ // and make sure the caller has the right to load a new uri into
+ // this frame.
+ nsCOMPtr parentItem;
+ rv = GetSameTypeParent(getter_AddRefs(parentItem));
+
+ if (NS_FAILED(rv) || !parentItem) {
+ return rv;
+ }
+
+ // We're a frame. Check that the caller has write permission to
+ // the parent before allowing it to load anything into this
+ // docshell.
+
+ nsCOMPtr securityManager =
+ do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr caller(do_QueryInterface(aOwner));
+
+ if (!caller) {
+ rv = securityManager->GetSubjectPrincipal(getter_AddRefs(caller));
+
+ if (NS_FAILED(rv) || !caller) {
+ // No principal reachable, permit load (assuming the above
+ // call didn't fail)
+
+ return rv;
+ }
+ }
+
+ if (!aOwner && caller) {
+ // We were *not* passed a principal, but we found a subject
+ // principal. That means that JS is running. Check if
+ // "UniversalBrowserWrite" is enabled, and allow the load if
+ // it is.
+
+ PRBool ubwEnabled = PR_FALSE;
+ rv = securityManager->IsCapabilityEnabled("UniversalBrowserWrite",
+ &ubwEnabled);
+ if (NS_FAILED(rv) || ubwEnabled) {
+ return rv;
+ }
+ }
+
+ nsCOMPtr sgo(do_GetInterface(parentItem));
+
+ nsCOMPtr sop(do_QueryInterface(sgo));
+
+ nsIPrincipal *parentPrincipal;
+ if (!sop || !(parentPrincipal = sop->GetPrincipal())) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ // Check if the caller is from the same origin as our parent.
+ rv = securityManager->CheckSameOriginPrincipal(caller, parentPrincipal);
+ if (NS_SUCCEEDED(rv)) {
+ // Same origin, permit load
+
+ return rv;
+ }
+
+ sop = do_QueryInterface(mScriptGlobal);
+
+ nsIPrincipal *principal;
+ if (!sop || !(principal = sop->GetPrincipal())) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ // Check if the caller is from the same origin as we are.
+ rv = securityManager->CheckSameOriginPrincipal(caller, principal);
+ if (NS_SUCCEEDED(rv)) {
+ // Same origin, permit load
+
+ return rv;
+ }
+
+ // Caller and callee are not from the same origin. Only permit
+ // loading content if both are part of the same window, assuming
+ // we can find the window of the caller.
+
+ nsCOMPtr sameTypeCalleeRoot;
+ GetSameTypeRootTreeItem(getter_AddRefs(sameTypeCalleeRoot));
+
+ nsCOMPtr stack =
+ do_GetService("@mozilla.org/js/xpc/ContextStack;1");
+ if (!stack) {
+ return rv;
+ }
+
+ JSContext *cx = nsnull;
+ stack->Peek(&cx);
+
+ if (!cx) {
+ // No caller docshell reachable, disallow load.
+
+ return rv;
+ }
+
+ nsIScriptContext *currentCX =
+ GetScriptContextFromJSContext(cx);
+ if (currentCX &&
+ (sgo = currentCX->GetGlobalObject())) {
+ nsCOMPtr sameTypeCallerRoot =
+ do_QueryInterface(sgo->GetDocShell());
+
+ if (sameTypeCalleeRoot == sameTypeCallerRoot) {
+ rv = NS_OK;
+ }
+ }
+
+ return rv;
+}
+
//*****************************************************************************
// nsDocShell: Site Loading
//*****************************************************************************
@@ -5199,7 +5330,12 @@ nsDocShell::InternalLoad(nsIURI * aURI,
if (mIsBeingDestroyed) {
return NS_ERROR_FAILURE;
}
-
+
+ rv = CheckLoadingPermissions(aOwner);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
mURIResultedInDocument = PR_FALSE; // reset the clock...
//
diff --git a/mozilla/docshell/base/nsDocShell.h b/mozilla/docshell/base/nsDocShell.h
index b7fd65137e6..1a7010030db 100644
--- a/mozilla/docshell/base/nsDocShell.h
+++ b/mozilla/docshell/base/nsDocShell.h
@@ -325,6 +325,9 @@ protected:
virtual nsresult EndPageLoad(nsIWebProgress * aProgress,
nsIChannel * aChannel,
nsresult aResult);
+
+ nsresult CheckLoadingPermissions(nsISupports *aOwner);
+
protected:
PRPackedBool mAllowSubframes;
PRPackedBool mAllowPlugins;
diff --git a/mozilla/docshell/base/nsWebShell.cpp b/mozilla/docshell/base/nsWebShell.cpp
index 7d05132dd61..1bd45e2719b 100644
--- a/mozilla/docshell/base/nsWebShell.cpp
+++ b/mozilla/docshell/base/nsWebShell.cpp
@@ -58,6 +58,7 @@
#include "nsIRefreshURI.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptGlobalObjectOwner.h"
+#include "nsIScriptSecurityManager.h"
#include "nsIDOMEvent.h"
#include "nsIPresContext.h"
#include "nsIComponentManager.h"
@@ -423,15 +424,17 @@ nsWebShell::SetRendering(PRBool aRender)
struct OnLinkClickEvent : public PLEvent {
OnLinkClickEvent(nsWebShell* aHandler, nsIContent* aContent,
nsLinkVerb aVerb, nsIURI* aURI,
- const PRUnichar* aTargetSpec, nsIInputStream* aPostDataStream = 0,
- nsIInputStream* aHeadersDataStream = 0);
+ const PRUnichar* aTargetSpec,
+ nsIInputStream* aPostDataStream,
+ nsIInputStream* aHeadersDataStream,
+ nsISupports *aOwner);
~OnLinkClickEvent();
void HandleEvent() {
- mHandler->OnLinkClickSync(mContent, mVerb, mURI,
- mTargetSpec.get(), mPostDataStream,
- mHeadersDataStream,
- nsnull, nsnull);
+ mHandler->OnLinkClickSyncInternal(mContent, mVerb, mURI,
+ mTargetSpec.get(), mPostDataStream,
+ mHeadersDataStream,
+ nsnull, nsnull, mOwner);
}
nsWebShell* mHandler;
@@ -441,6 +444,7 @@ struct OnLinkClickEvent : public PLEvent {
nsCOMPtr mHeadersDataStream;
nsCOMPtr mContent;
nsLinkVerb mVerb;
+ nsCOMPtr mOwner;
};
static void PR_CALLBACK HandlePLEvent(OnLinkClickEvent* aEvent)
@@ -459,7 +463,8 @@ OnLinkClickEvent::OnLinkClickEvent(nsWebShell* aHandler,
nsIURI* aURI,
const PRUnichar* aTargetSpec,
nsIInputStream* aPostDataStream,
- nsIInputStream* aHeadersDataStream)
+ nsIInputStream* aHeadersDataStream,
+ nsISupports *aOwner)
{
mHandler = aHandler;
NS_ADDREF(aHandler);
@@ -469,6 +474,7 @@ OnLinkClickEvent::OnLinkClickEvent(nsWebShell* aHandler,
mHeadersDataStream = aHeadersDataStream;
mContent = aContent;
mVerb = aVerb;
+ mOwner = aOwner;
PL_InitEvent(this, nsnull,
(PLHandleEventProc) ::HandlePLEvent,
@@ -496,10 +502,20 @@ nsWebShell::OnLinkClick(nsIContent* aContent,
nsIInputStream* aPostDataStream,
nsIInputStream* aHeadersDataStream)
{
- OnLinkClickEvent* ev;
+ nsCOMPtr securityManager =
+ do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
+ NS_ENSURE_TRUE(securityManager, NS_ERROR_UNEXPECTED);
- ev = new OnLinkClickEvent(this, aContent, aVerb, aURI,
- aTargetSpec, aPostDataStream, aHeadersDataStream);
+ nsCOMPtr principal;
+ securityManager->GetSubjectPrincipal(getter_AddRefs(principal));
+
+ if (!principal && aContent && aContent->GetDocument()) {
+ principal = aContent->GetDocument()->GetPrincipal();
+ }
+
+ OnLinkClickEvent* ev =
+ new OnLinkClickEvent(this, aContent, aVerb, aURI, aTargetSpec,
+ aPostDataStream, aHeadersDataStream, principal);
if (!ev) {
return NS_ERROR_OUT_OF_MEMORY;
}
@@ -518,7 +534,7 @@ nsWebShell::GetEventQueue(nsIEventQueue **aQueue)
return *aQueue ? NS_OK : NS_ERROR_FAILURE;
}
-NS_IMETHODIMP
+nsresult
nsWebShell::OnLinkClickSync(nsIContent *aContent,
nsLinkVerb aVerb,
nsIURI* aURI,
@@ -528,7 +544,33 @@ nsWebShell::OnLinkClickSync(nsIContent *aContent,
nsIDocShell** aDocShell,
nsIRequest** aRequest)
{
- PRBool earlyReturn = PR_FALSE;
+ nsCOMPtr securityManager =
+ do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
+ NS_ENSURE_TRUE(securityManager, NS_ERROR_UNEXPECTED);
+
+ nsCOMPtr principal;
+ securityManager->GetSubjectPrincipal(getter_AddRefs(principal));
+
+ if (!principal && aContent && aContent->GetDocument()) {
+ principal = aContent->GetDocument()->GetPrincipal();
+ }
+
+ return OnLinkClickSyncInternal(aContent, aVerb, aURI, aTargetSpec,
+ aPostDataStream, aHeadersDataStream,
+ aDocShell, aRequest, principal);
+}
+
+nsresult
+nsWebShell::OnLinkClickSyncInternal(nsIContent *aContent,
+ nsLinkVerb aVerb,
+ nsIURI* aURI,
+ const PRUnichar* aTargetSpec,
+ nsIInputStream* aPostDataStream,
+ nsIInputStream* aHeadersDataStream,
+ nsIDocShell** aDocShell,
+ nsIRequest** aRequest,
+ nsISupports *aOwner)
+{
{
// defer to an external protocol handler if necessary...
nsCOMPtr extProtService = do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID);
@@ -542,16 +584,15 @@ nsWebShell::OnLinkClickSync(nsIContent *aContent,
nsresult rv = extProtService->IsExposedProtocol(scheme.get(), &isExposed);
if (NS_SUCCEEDED(rv) && !isExposed) {
rv = extProtService->LoadUrl(aURI);
+
if (NS_SUCCEEDED(rv))
- earlyReturn = PR_TRUE;
- else
- NS_WARNING("failed to launch external protocol handler");
+ return NS_OK;
+
+ NS_WARNING("failed to launch external protocol handler");
}
}
}
}
- if (earlyReturn)
- return NS_OK;
nsCOMPtr node(do_QueryInterface(aContent));
NS_ENSURE_TRUE(node, NS_ERROR_UNEXPECTED);
@@ -563,7 +604,7 @@ nsWebShell::OnLinkClickSync(nsIContent *aContent,
aURI->SchemeIs("data", &isData);
if (isJS || isData) {
- nsCOMPtr sourceDoc = aContent->GetDocument();
+ nsIDocument *sourceDoc = aContent->GetDocument();
if (!sourceDoc) {
// The source is in a 'zombie' document, or not part of a
@@ -631,7 +672,7 @@ nsWebShell::OnLinkClickSync(nsIContent *aContent,
{
return InternalLoad(aURI, // New URI
referer, // Referer URI
- nsnull, // No onwer
+ aOwner, // Owner (nsIPrincipal)
PR_TRUE, // Inherit owner from document
target.get(), // Window target
NS_LossyConvertUCS2toASCII(typeHint).get(),
diff --git a/mozilla/docshell/base/nsWebShell.h b/mozilla/docshell/base/nsWebShell.h
index 80e5a9a4322..b0e73653118 100644
--- a/mozilla/docshell/base/nsWebShell.h
+++ b/mozilla/docshell/base/nsWebShell.h
@@ -115,6 +115,15 @@ public:
// NS_IMETHOD SetURL(const PRUnichar* aURL);
+ nsresult OnLinkClickSyncInternal(nsIContent* aContent, nsLinkVerb aVerb,
+ nsIURI* aURI,
+ const PRUnichar* aTargetSpec,
+ nsIInputStream* aPostDataStream,
+ nsIInputStream* aHeadersDataStream,
+ nsIDocShell** aDocShell,
+ nsIRequest** aRequest,
+ nsISupports *aOwner);
+
protected:
// void GetRootWebShellEvenIfChrome(nsIWebShell** aResult);
void InitFrameData();