--- a/content/base/src/nsDOMParser.cpp
+++ b/content/base/src/nsDOMParser.cpp
@@ -52,16 +52,18 @@
#include "nsCRT.h"
#include "nsLoadListenerProxy.h"
#include "nsStreamUtils.h"
#include "nsThreadUtils.h"
#include "nsNetCID.h"
#include "nsContentUtils.h"
#include "nsDOMJSUtils.h"
#include "nsDOMError.h"
+#include "nsIDOMWindow.h"
+#include "nsPIDOMWindow.h"
// nsIDOMEventListener
nsresult
nsDOMParser::HandleEvent(nsIDOMEvent* aEvent)
{
return NS_OK;
}
@@ -421,17 +423,17 @@ GetInitArgs(JSContext *cx, PRUint32 argc
NS_IF_ADDREF(*aPrincipal = prin);
NS_IF_ADDREF(*aDocumentURI = documentURI);
NS_IF_ADDREF(*aBaseURI = baseURI);
return NS_OK;
}
NS_IMETHODIMP
-nsDOMParser::Initialize(JSContext *cx, JSObject* obj,
+nsDOMParser::Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
PRUint32 argc, jsval *argv)
{
AttemptedInitMarker marker(&mAttemptedInit);
nsCOMPtr<nsIPrincipal> prin;
nsCOMPtr<nsIURI> documentURI;
nsCOMPtr<nsIURI> baseURI;
if (argc > 0) {
nsresult rv = GetInitArgs(cx, argc, argv, getter_AddRefs(prin),
@@ -458,30 +460,34 @@ nsDOMParser::Initialize(JSContext *cx, J
// Note that this is a behavior change as far as I can tell -- we're now
// using the base URI and document URI of the window off of which the
// DOMParser is created, not the window in which parse*() is called.
// Does that matter?
// Also note that |cx| matches what GetDocumentFromContext() would return,
// while GetDocumentFromCaller() gives us the window that the DOMParser()
// call was made on.
-
- nsCOMPtr<nsIDocument> doc =
- do_QueryInterface(nsContentUtils::GetDocumentFromCaller());
+
+ nsCOMPtr<nsIDocument> doc;
+ nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aOwner);
+ if (aOwner) {
+ nsCOMPtr<nsIDOMDocument> domdoc = window->GetExtantDocument();
+ doc = do_QueryInterface(domdoc);
+ }
+
if (!doc) {
return NS_ERROR_UNEXPECTED;
}
baseURI = doc->GetBaseURI();
documentURI = doc->GetDocumentURI();
}
- nsIScriptContext* scriptContext = GetScriptContextFromJSContext(cx);
- return Init(prin, documentURI, baseURI,
- scriptContext ? scriptContext->GetGlobalObject() : nsnull);
+ nsCOMPtr<nsIScriptGlobalObject> scriptglobal = do_QueryInterface(aOwner);
+ return Init(prin, documentURI, baseURI, scriptglobal);
}
NS_IMETHODIMP
nsDOMParser::Init()
{
AttemptedInitMarker marker(&mAttemptedInit);
nsCOMPtr<nsIXPCNativeCallContext> ncc;
--- a/content/base/src/nsDOMParser.h
+++ b/content/base/src/nsDOMParser.h
@@ -69,17 +69,17 @@ public:
// nsIDOMLoadListener
NS_IMETHOD Load(nsIDOMEvent* aEvent);
NS_IMETHOD BeforeUnload(nsIDOMEvent* aEvent);
NS_IMETHOD Unload(nsIDOMEvent* aEvent);
NS_IMETHOD Abort(nsIDOMEvent* aEvent);
NS_IMETHOD Error(nsIDOMEvent* aEvent);
// nsIJSNativeInitializer
- NS_IMETHOD Initialize(JSContext *cx, JSObject *obj,
+ NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
PRUint32 argc, jsval *argv);
private:
class AttemptedInitMarker {
public:
AttemptedInitMarker(PRPackedBool* aAttemptedInit) :
mAttemptedInit(aAttemptedInit)
{}
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -2580,30 +2580,33 @@ nsDocument::GetScriptHandlingObject(PRBo
if (mScriptGlobalObject) {
return mScriptGlobalObject;
}
nsCOMPtr<nsIScriptGlobalObject> scriptHandlingObject =
do_QueryReferent(mScriptObject);
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(scriptHandlingObject);
if (win) {
+ NS_ASSERTION(win->IsInnerWindow(), "Should have inner window here!");
nsPIDOMWindow* outer = win->GetOuterWindow();
if (!outer || outer->GetCurrentInnerWindow() != win) {
NS_WARNING("Wrong inner/outer window combination!");
return nsnull;
}
}
return scriptHandlingObject;
}
void
nsDocument::SetScriptHandlingObject(nsIScriptGlobalObject* aScriptObject)
{
NS_ASSERTION(!mScriptGlobalObject ||
mScriptGlobalObject == aScriptObject,
"Wrong script object!");
+ nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aScriptObject);
+ NS_ASSERTION(!win || win->IsInnerWindow(), "Should have inner window here!");
mScriptObject = do_GetWeakReference(aScriptObject);
if (aScriptObject) {
mHasHadScriptHandlingObject = PR_TRUE;
}
}
nsPIDOMWindow *
nsDocument::GetWindow()
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -84,16 +84,17 @@
#include "nsContentPolicyUtils.h"
#include "nsContentErrors.h"
#include "nsLayoutStatics.h"
#include "nsCrossSiteListenerProxy.h"
#include "nsDOMError.h"
#include "nsIHTMLDocument.h"
#include "nsWhitespaceTokenizer.h"
#include "nsIMultiPartChannel.h"
+#include "nsIScriptObjectPrincipal.h"
#define LOAD_STR "load"
#define ERROR_STR "error"
#define PROGRESS_STR "progress"
#define UPLOADPROGRESS_STR "uploadprogress"
#define READYSTATE_STR "readystatechange"
// CIDs
@@ -333,37 +334,16 @@ nsACProxyListener::OnChannelRedirect(nsI
}
NS_IMETHODIMP
nsACProxyListener::GetInterface(const nsIID & aIID, void **aResult)
{
return QueryInterface(aIID, aResult);
}
-
-static nsIScriptContext *
-GetCurrentContext()
-{
- // Get JSContext from stack.
- nsCOMPtr<nsIJSContextStack> stack =
- do_GetService("@mozilla.org/js/xpc/ContextStack;1");
-
- if (!stack) {
- return nsnull;
- }
-
- JSContext *cx;
-
- if (NS_FAILED(stack->Peek(&cx)) || !cx) {
- return nsnull;
- }
-
- return GetScriptContextFromJSContext(cx);
-}
-
/**
* Gets the nsIDocument given the script context. Will return nsnull on failure.
*
* @param aScriptContext the script context to get the document for; can be null
*
* @return the document associated with the script context
*/
static already_AddRefed<nsIDocument>
@@ -407,16 +387,78 @@ nsXMLHttpRequest::~nsXMLHttpRequest()
NS_ABORT_IF_FALSE(!(mState & XML_HTTP_REQUEST_SYNCLOOPING), "we rather crash than hang");
mState &= ~XML_HTTP_REQUEST_SYNCLOOPING;
// Needed to free the listener arrays.
ClearEventListeners();
nsLayoutStatics::Release();
}
+nsresult
+nsXMLHttpRequest::Init()
+{
+ // Set the original mScriptContext and mPrincipal, if available.
+ // Get JSContext from stack.
+ nsCOMPtr<nsIJSContextStack> stack =
+ do_GetService("@mozilla.org/js/xpc/ContextStack;1");
+
+ if (!stack) {
+ return NS_OK;
+ }
+
+ JSContext *cx;
+
+ if (NS_FAILED(stack->Peek(&cx)) || !cx) {
+ return NS_OK;
+ }
+
+ nsIScriptContext* context = GetScriptContextFromJSContext(cx);
+ if (!context) {
+ return NS_OK;
+ }
+ nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
+ nsCOMPtr<nsIPrincipal> subjectPrincipal;
+ if (secMan) {
+ secMan->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
+ }
+ NS_ENSURE_STATE(subjectPrincipal);
+
+ mScriptContext = context;
+ mPrincipal = subjectPrincipal;
+ nsCOMPtr<nsPIDOMWindow> window =
+ do_QueryInterface(context->GetGlobalObject());
+ if (window) {
+ mOwner = window->GetCurrentInnerWindow();
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLHttpRequest::Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
+ PRUint32 argc, jsval *argv)
+{
+ mOwner = do_QueryInterface(aOwner);
+ if (!mOwner) {
+ NS_WARNING("Unexpected nsIJSNativeInitializer owner");
+ return NS_OK;
+ }
+
+ // This XHR object is bound to a |window|,
+ // so re-set principal and script context.
+ nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal = do_QueryInterface(aOwner);
+ NS_ENSURE_STATE(scriptPrincipal);
+ mPrincipal = scriptPrincipal->GetPrincipal();
+ nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aOwner);
+ NS_ENSURE_STATE(sgo);
+ mScriptContext = sgo->GetContext();
+ NS_ENSURE_STATE(mScriptContext);
+ return NS_OK;
+}
+
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLHttpRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXMLHttpRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannel)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mReadRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mLoadEventListeners)
@@ -431,16 +473,18 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnProgressListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnUploadProgressListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnReadystatechangeListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mXMLParserStreamListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannelEventSink)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mProgressEventSink)
+
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOwner)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXMLHttpRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContext)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannel)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mReadRequest)
@@ -456,32 +500,35 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnProgressListener)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnUploadProgressListener)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnReadystatechangeListener)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mXMLParserStreamListener)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannelEventSink)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mProgressEventSink)
+
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOwner)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
// QueryInterface implementation for nsXMLHttpRequest
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXMLHttpRequest)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXMLHttpRequest)
NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequest)
NS_INTERFACE_MAP_ENTRY(nsIJSXMLHttpRequest)
NS_INTERFACE_MAP_ENTRY(nsIDOMLoadListener)
NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
NS_INTERFACE_MAP_ENTRY(nsIProgressEventSink)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+ NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(XMLHttpRequest)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsXMLHttpRequest, nsIXMLHttpRequest)
NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsXMLHttpRequest, nsIXMLHttpRequest)
@@ -507,18 +554,16 @@ nsXMLHttpRequest::AddEventListener(const
IMPL_ADD_LISTENER(UPLOADPROGRESS_STR, mUploadProgressEventListeners)
IMPL_ADD_LISTENER(READYSTATE_STR, mReadystatechangeEventListeners)
{
return NS_ERROR_INVALID_ARG;
}
array->AppendObject(listener);
- mScriptContext = GetCurrentContext();
-
#undef IMPL_ADD_LISTENER
return NS_OK;
}
/* void removeEventListener (in string type, in nsIDOMEventListener
listener); */
NS_IMETHODIMP
@@ -573,19 +618,16 @@ nsXMLHttpRequest::GetOnreadystatechange(
return NS_OK;
}
NS_IMETHODIMP
nsXMLHttpRequest::SetOnreadystatechange(nsIDOMEventListener * aOnreadystatechange)
{
mOnReadystatechangeListener = aOnreadystatechange;
-
- mScriptContext = GetCurrentContext();
-
return NS_OK;
}
/* attribute nsIDOMEventListener onload; */
NS_IMETHODIMP
nsXMLHttpRequest::GetOnload(nsIDOMEventListener * *aOnLoad)
{
@@ -595,19 +637,16 @@ nsXMLHttpRequest::GetOnload(nsIDOMEventL
return NS_OK;
}
NS_IMETHODIMP
nsXMLHttpRequest::SetOnload(nsIDOMEventListener * aOnLoad)
{
mOnLoadListener = aOnLoad;
-
- mScriptContext = GetCurrentContext();
-
return NS_OK;
}
/* attribute nsIDOMEventListener onerror; */
NS_IMETHODIMP
nsXMLHttpRequest::GetOnerror(nsIDOMEventListener * *aOnerror)
{
NS_ENSURE_ARG_POINTER(aOnerror);
@@ -616,19 +655,16 @@ nsXMLHttpRequest::GetOnerror(nsIDOMEvent
return NS_OK;
}
NS_IMETHODIMP
nsXMLHttpRequest::SetOnerror(nsIDOMEventListener * aOnerror)
{
mOnErrorListener = aOnerror;
-
- mScriptContext = GetCurrentContext();
-
return NS_OK;
}
/* attribute nsIDOMEventListener onprogress; */
NS_IMETHODIMP
nsXMLHttpRequest::GetOnprogress(nsIDOMEventListener * *aOnprogress)
{
NS_ENSURE_ARG_POINTER(aOnprogress);
@@ -637,19 +673,16 @@ nsXMLHttpRequest::GetOnprogress(nsIDOMEv
return NS_OK;
}
NS_IMETHODIMP
nsXMLHttpRequest::SetOnprogress(nsIDOMEventListener * aOnprogress)
{
mOnProgressListener = aOnprogress;
-
- mScriptContext = GetCurrentContext();
-
return NS_OK;
}
/* attribute nsIDOMEventListener onuploadprogress; */
NS_IMETHODIMP
nsXMLHttpRequest::GetOnuploadprogress(nsIDOMEventListener * *aOnuploadprogress)
{
NS_ENSURE_ARG_POINTER(aOnuploadprogress);
@@ -658,19 +691,16 @@ nsXMLHttpRequest::GetOnuploadprogress(ns
return NS_OK;
}
NS_IMETHODIMP
nsXMLHttpRequest::SetOnuploadprogress(nsIDOMEventListener * aOnuploadprogress)
{
mOnUploadProgressListener = aOnuploadprogress;
-
- mScriptContext = GetCurrentContext();
-
return NS_OK;
}
/* readonly attribute nsIChannel channel; */
NS_IMETHODIMP
nsXMLHttpRequest::GetChannel(nsIChannel **aChannel)
{
NS_ENSURE_ARG_POINTER(aChannel);
@@ -978,36 +1008,29 @@ nsXMLHttpRequest::GetResponseHeader(cons
}
nsresult
nsXMLHttpRequest::GetLoadGroup(nsILoadGroup **aLoadGroup)
{
NS_ENSURE_ARG_POINTER(aLoadGroup);
*aLoadGroup = nsnull;
- if (!mScriptContext) {
- mScriptContext = GetCurrentContext();
- }
-
nsCOMPtr<nsIDocument> doc = GetDocumentFromScriptContext(mScriptContext);
if (doc) {
*aLoadGroup = doc->GetDocumentLoadGroup().get(); // already_AddRefed
}
return NS_OK;
}
nsIURI *
nsXMLHttpRequest::GetBaseURI()
{
if (!mScriptContext) {
- mScriptContext = GetCurrentContext();
- if (!mScriptContext) {
- return nsnull;
- }
+ return nsnull;
}
nsCOMPtr<nsIDocument> doc = GetDocumentFromScriptContext(mScriptContext);
if (!doc) {
return nsnull;
}
return doc->GetBaseURI();
@@ -1062,16 +1085,20 @@ nsXMLHttpRequest::NotifyEventListeners(c
// XXXbz wouldn't it be easier to just have an actual nsEventListenerManager
// to work with or something? I feel like we're duplicating code here...
if (!aEvent)
return;
nsCOMPtr<nsIJSContextStack> stack;
JSContext *cx = nsnull;
+ if (NS_FAILED(CheckInnerWindowCorrectness())) {
+ return;
+ }
+
if (mScriptContext) {
stack = do_GetService("@mozilla.org/js/xpc/ContextStack;1");
if (stack) {
cx = (JSContext *)mScriptContext->GetNativeContext();
if (cx) {
stack->Push(cx);
@@ -1204,30 +1231,16 @@ nsXMLHttpRequest::OpenRequest(const nsAC
// Disallow HTTP/1.1 TRACE method (see bug 302489)
// and MS IIS equivalent TRACK (see bug 381264)
if (method.LowerCaseEqualsLiteral("trace") ||
method.LowerCaseEqualsLiteral("track")) {
return NS_ERROR_INVALID_ARG;
}
- // Get the principal.
- // XXX This should be done at construction time.
- nsCOMPtr<nsIDocument> doc =
- do_QueryInterface(nsContentUtils::GetDocumentFromCaller());
- if (doc) {
- mPrincipal = doc->NodePrincipal();
- }
- else {
- nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
- if (secMan) {
- secMan->GetSubjectPrincipal(getter_AddRefs(mPrincipal));
- }
- }
-
nsresult rv;
nsCOMPtr<nsIURI> uri;
PRBool authp = PR_FALSE;
if (mState & (XML_HTTP_REQUEST_OPENED |
XML_HTTP_REQUEST_LOADED |
XML_HTTP_REQUEST_INTERACTIVE |
XML_HTTP_REQUEST_SENT |
@@ -1257,21 +1270,23 @@ nsXMLHttpRequest::OpenRequest(const nsAC
mState &= ~XML_HTTP_REQUEST_ASYNC;
}
rv = NS_NewURI(getter_AddRefs(uri), url, nsnull, GetBaseURI());
if (NS_FAILED(rv)) return rv;
// mScriptContext should be initialized because of GetBaseURI() above.
// Still need to consider the case that doc is nsnull however.
- doc = GetDocumentFromScriptContext(mScriptContext);
+ rv = CheckInnerWindowCorrectness();
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsIDocument> doc = GetDocumentFromScriptContext(mScriptContext);
PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_XMLHTTPREQUEST,
uri,
- (doc ? doc->NodePrincipal() : nsnull),
+ mPrincipal,
doc,
EmptyCString(), //mime guess
nsnull, //extra
&shouldLoad,
nsContentUtils::GetContentPolicy(),
nsContentUtils::GetSecurityManager());
if (NS_FAILED(rv)) return rv;
if (NS_CP_REJECTED(shouldLoad)) {
@@ -1547,18 +1562,17 @@ nsXMLHttpRequest::OnStartRequest(nsIRequ
mContext = ctxt;
mState |= XML_HTTP_REQUEST_PARSEBODY;
ChangeState(XML_HTTP_REQUEST_LOADED);
nsIURI* uri = GetBaseURI();
// Create an empty document from it
const nsAString& emptyStr = EmptyString();
- nsIScriptGlobalObject* global = mScriptContext ?
- mScriptContext->GetGlobalObject() : nsnull;
+ nsCOMPtr<nsIScriptGlobalObject> global = do_QueryInterface(mOwner);
nsresult rv = nsContentUtils::CreateDocument(emptyStr, emptyStr, nsnull, uri,
uri, mPrincipal, global,
getter_AddRefs(mDocument));
NS_ENSURE_SUCCESS(rv, rv);
if (mState & XML_HTTP_REQUEST_USE_XSITE_AC) {
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
if (htmlDoc) {
@@ -1819,17 +1833,18 @@ nsXMLHttpRequest::SendAsBinary(const nsA
return Send(variant);
}
/* void send (in nsIVariant aBody); */
NS_IMETHODIMP
nsXMLHttpRequest::Send(nsIVariant *aBody)
{
- nsresult rv;
+ nsresult rv = CheckInnerWindowCorrectness();
+ NS_ENSURE_SUCCESS(rv, rv);
// Return error if we're already processing a request
if (XML_HTTP_REQUEST_SENT & mState) {
return NS_ERROR_FAILURE;
}
// Make sure we've been opened
if (!mChannel || !(XML_HTTP_REQUEST_OPENED & mState)) {
@@ -2011,21 +2026,16 @@ nsXMLHttpRequest::Send(nsIVariant *aBody
// Reset responseXML
mDocument = nsnull;
if (!(mState & XML_HTTP_REQUEST_ASYNC)) {
mState |= XML_HTTP_REQUEST_SYNCLOOPING;
}
- if (!mScriptContext) {
- // We need a context to check if redirect (if any) is allowed
- mScriptContext = GetCurrentContext();
- }
-
rv = CheckChannelForCrossSiteRequest();
NS_ENSURE_SUCCESS(rv, rv);
// Hook us up to listen to redirects and the like
mChannel->GetNotificationCallbacks(getter_AddRefs(mNotificationCallbacks));
mChannel->SetNotificationCallbacks(this);
// Create our listener
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -55,30 +55,32 @@
#include "nsIChannelEventSink.h"
#include "nsIInterfaceRequestor.h"
#include "nsIHttpHeaderVisitor.h"
#include "nsIProgressEventSink.h"
#include "nsCOMArray.h"
#include "nsJSUtils.h"
#include "nsTArray.h"
#include "nsCycleCollectionParticipant.h"
-
+#include "nsIJSNativeInitializer.h"
+#include "nsPIDOMWindow.h"
#include "nsIDOMLSProgressEvent.h"
class nsILoadGroup;
class nsXMLHttpRequest : public nsIXMLHttpRequest,
public nsIJSXMLHttpRequest,
public nsIDOMLoadListener,
public nsIDOMEventTarget,
public nsIStreamListener,
public nsIChannelEventSink,
public nsIProgressEventSink,
public nsIInterfaceRequestor,
- public nsSupportsWeakReference
+ public nsSupportsWeakReference,
+ public nsIJSNativeInitializer
{
public:
nsXMLHttpRequest();
virtual ~nsXMLHttpRequest();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
// nsIXMLHttpRequest
@@ -110,16 +112,23 @@ public:
NS_DECL_NSICHANNELEVENTSINK
// nsIProgressEventSink
NS_DECL_NSIPROGRESSEVENTSINK
// nsIInterfaceRequestor
NS_DECL_NSIINTERFACEREQUESTOR
+ // nsIJSNativeInitializer
+ NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
+ PRUint32 argc, jsval* argv);
+
+ // This is called by the factory constructor.
+ nsresult Init();
+
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXMLHttpRequest, nsIXMLHttpRequest)
protected:
nsresult DetectCharset(nsACString& aCharset);
nsresult ConvertBodyToText(nsAString& aOutBuffer);
static NS_METHOD StreamReaderFunc(nsIInputStream* in,
void* closure,
@@ -160,31 +169,44 @@ protected:
/**
* Check if mChannel is ok for a cross-site request by making sure no
* inappropriate headers are set, and no username/password is set.
*
* Also updates the XML_HTTP_REQUEST_USE_XSITE_AC bit.
*/
nsresult CheckChannelForCrossSiteRequest();
+ nsresult CheckInnerWindowCorrectness()
+ {
+ if (mOwner) {
+ NS_ASSERTION(mOwner->IsInnerWindow(), "Should have inner window here!\n");
+ nsPIDOMWindow* outer = mOwner->GetOuterWindow();
+ if (!outer || outer->GetCurrentInnerWindow() != mOwner) {
+ return NS_ERROR_FAILURE;
+ }
+ }
+ return NS_OK;
+ }
+
nsCOMPtr<nsISupports> mContext;
nsCOMPtr<nsIPrincipal> mPrincipal;
nsCOMPtr<nsIChannel> mChannel;
// mReadRequest is different from mChannel for multipart requests
nsCOMPtr<nsIRequest> mReadRequest;
nsCOMPtr<nsIDOMDocument> mDocument;
nsCOMPtr<nsIChannel> mACGetChannel;
nsCOMArray<nsIDOMEventListener> mLoadEventListeners;
nsCOMArray<nsIDOMEventListener> mErrorEventListeners;
nsCOMArray<nsIDOMEventListener> mProgressEventListeners;
nsCOMArray<nsIDOMEventListener> mUploadProgressEventListeners;
nsCOMArray<nsIDOMEventListener> mReadystatechangeEventListeners;
nsCOMPtr<nsIScriptContext> mScriptContext;
+ nsCOMPtr<nsPIDOMWindow> mOwner; // Inner window.
nsCOMPtr<nsIDOMEventListener> mOnLoadListener;
nsCOMPtr<nsIDOMEventListener> mOnErrorListener;
nsCOMPtr<nsIDOMEventListener> mOnProgressListener;
nsCOMPtr<nsIDOMEventListener> mOnUploadProgressListener;
nsCOMPtr<nsIDOMEventListener> mOnReadystatechangeListener;
nsCOMPtr<nsIStreamListener> mXMLParserStreamListener;
--- a/content/html/content/src/nsHTMLImageElement.cpp
+++ b/content/html/content/src/nsHTMLImageElement.cpp
@@ -103,18 +103,18 @@ public:
// nsIDOMHTMLImageElement
NS_DECL_NSIDOMHTMLIMAGEELEMENT
// nsIDOMNSHTMLImageElement
NS_DECL_NSIDOMNSHTMLIMAGEELEMENT
// nsIJSNativeInitializer
- NS_IMETHOD Initialize(JSContext* aContext, JSObject *aObj,
- PRUint32 argc, jsval *argv);
+ NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aContext,
+ JSObject* aObj, PRUint32 argc, jsval* argv);
// nsIContent
virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult);
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
PRInt32 aModType) const;
@@ -537,18 +537,18 @@ nsHTMLImageElement::BindToTree(nsIDocume
PRInt32
nsHTMLImageElement::IntrinsicState() const
{
return nsGenericHTMLElement::IntrinsicState() |
nsImageLoadingContent::ImageState();
}
NS_IMETHODIMP
-nsHTMLImageElement::Initialize(JSContext* aContext, JSObject *aObj,
- PRUint32 argc, jsval *argv)
+nsHTMLImageElement::Initialize(nsISupports* aOwner, JSContext* aContext,
+ JSObject *aObj, PRUint32 argc, jsval *argv)
{
if (argc <= 0) {
// Nothing to do here if we don't get any arguments.
return NS_OK;
}
// The first (optional) argument is the width of the image
--- a/content/html/content/src/nsHTMLOptionElement.cpp
+++ b/content/html/content/src/nsHTMLOptionElement.cpp
@@ -97,18 +97,18 @@ public:
// nsIDOMHTMLOptionElement
NS_DECL_NSIDOMHTMLOPTIONELEMENT
// nsIDOMNSHTMLOptionElement
NS_IMETHOD SetText(const nsAString & aText);
// nsIJSNativeInitializer
- NS_IMETHOD Initialize(JSContext* aContext, JSObject *aObj,
- PRUint32 argc, jsval *argv);
+ NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aContext,
+ JSObject *aObj, PRUint32 argc, jsval *argv);
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
PRInt32 aModType) const;
virtual nsresult BeforeSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
const nsAString* aValue, PRBool aNotify);
// nsIOptionElement
@@ -450,17 +450,18 @@ nsHTMLOptionElement::GetSelect()
break;
}
}
return nsnull;
}
NS_IMETHODIMP
-nsHTMLOptionElement::Initialize(JSContext* aContext,
+nsHTMLOptionElement::Initialize(nsISupports* aOwner,
+ JSContext* aContext,
JSObject *aObj,
PRUint32 argc,
jsval *argv)
{
nsresult result = NS_OK;
if (argc > 0) {
// The first (optional) parameter is the text of the option
--- a/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp
+++ b/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp
@@ -1253,18 +1253,18 @@ txMozillaXSLTProcessor::ContentRemoved(n
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
mStylesheet = nsnull;
}
NS_IMETHODIMP
-txMozillaXSLTProcessor::Initialize(JSContext* cx, JSObject* obj,
- PRUint32 argc, jsval* argv)
+txMozillaXSLTProcessor::Initialize(nsISupports* aOwner, JSContext* cx,
+ JSObject* obj, PRUint32 argc, jsval* argv)
{
nsCOMPtr<nsIPrincipal> prin;
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
NS_ENSURE_TRUE(secMan, NS_ERROR_UNEXPECTED);
secMan->GetSubjectPrincipal(getter_AddRefs(prin));
NS_ENSURE_TRUE(prin, NS_ERROR_UNEXPECTED);
--- a/content/xslt/src/xslt/txMozillaXSLTProcessor.h
+++ b/content/xslt/src/xslt/txMozillaXSLTProcessor.h
@@ -137,17 +137,17 @@ public:
nsIDOMDocument **aResult);
PRBool IsLoadDisabled()
{
return (mFlags & DISABLE_ALL_LOADS) != 0;
}
// nsIJSNativeInitializer
- NS_IMETHODIMP Initialize(JSContext *cx, JSObject *obj,
+ NS_IMETHODIMP Initialize(nsISupports* aOwner, JSContext *cx, JSObject *obj,
PRUint32 argc, jsval *argv);
static nsresult Startup();
static void Shutdown();
private:
nsresult DoTransform();
void notifyError();
--- a/dom/public/nsIJSNativeInitializer.h
+++ b/dom/public/nsIJSNativeInitializer.h
@@ -37,34 +37,34 @@
#ifndef nsIJSNativeInitializer_h__
#define nsIJSNativeInitializer_h__
#include "nsISupports.h"
#include "jsapi.h"
#define NS_IJSNATIVEINITIALIZER_IID \
-{0xa6cf90f4, 0x15b3, 0x11d2, \
- {0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
+{ 0x536c5ad2, 0x1275, 0x4706, \
+ { 0x99, 0xbd, 0x4a, 0xef, 0xb2, 0x4a, 0xb7, 0xf7 } }
/**
* A JavaScript specific interface used to initialize new
* native objects, created as a result of calling a
* JavaScript constructor. The arguments are passed in
* their raw form as jsval's.
*/
class nsIJSNativeInitializer : public nsISupports {
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IJSNATIVEINITIALIZER_IID)
/**
- * Intialize a newly created native instance using the parameters
- * passed into the JavaScript constructor.
+ * Initialize a newly created native instance using the owner of the
+ * constructor and the parameters passed into the JavaScript constructor.
*/
- NS_IMETHOD Initialize(JSContext *cx, JSObject *obj,
+ NS_IMETHOD Initialize(nsISupports* aOwner, JSContext *cx, JSObject *obj,
PRUint32 argc, jsval *argv) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIJSNativeInitializer,
NS_IJSNATIVEINITIALIZER_IID)
#endif // nsIJSNativeInitializer_h__
--- a/dom/src/base/nsDOMClassInfo.cpp
+++ b/dom/src/base/nsDOMClassInfo.cpp
@@ -4729,17 +4729,18 @@ FindConstructorContractID(PRInt32 aDOMCl
if (kConstructorMap[i].mDOMClassInfoID == aDOMClassInfoID) {
return kConstructorMap[i].mContractID;
}
}
return nsnull;
}
static nsresult
-BaseStubConstructor(const nsGlobalNameStruct *name_struct, JSContext *cx,
+BaseStubConstructor(nsIWeakReference* aWeakOwner,
+ const nsGlobalNameStruct *name_struct, JSContext *cx,
JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsresult rv;
nsCOMPtr<nsISupports> native;
if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) {
const char *contractid =
FindConstructorContractID(name_struct->mDOMClassInfoID);
native = do_CreateInstance(contractid, &rv);
@@ -4752,17 +4753,19 @@ BaseStubConstructor(const nsGlobalNameSt
}
if (NS_FAILED(rv)) {
NS_ERROR("Failed to create the object");
return rv;
}
nsCOMPtr<nsIJSNativeInitializer> initializer(do_QueryInterface(native));
if (initializer) {
- rv = initializer->Initialize(cx, obj, argc, argv);
+ nsCOMPtr<nsISupports> owner = do_QueryReferent(aWeakOwner);
+ NS_ENSURE_STATE(owner);
+ rv = initializer->Initialize(owner, cx, obj, argc, argv);
if (NS_FAILED(rv)) {
return NS_ERROR_NOT_INITIALIZED;
}
}
nsCOMPtr<nsIScriptObjectOwner> owner(do_QueryInterface(native));
if (owner) {
nsIScriptContext *context = nsJSUtils::GetStaticScriptContext(cx, obj);
@@ -4860,19 +4863,21 @@ DefineInterfaceConstants(JSContext *cx,
return NS_OK;
}
class nsDOMConstructor : public nsIDOMDOMConstructor
{
public:
nsDOMConstructor(const PRUnichar *aName,
- const nsGlobalNameStruct *aNameStruct)
+ const nsGlobalNameStruct *aNameStruct,
+ nsISupports* aOwner)
: mClassName(aName),
- mConstructable(IsConstructable(aNameStruct))
+ mConstructable(IsConstructable(aNameStruct)),
+ mWeakOwner(do_GetWeakReference(aOwner))
{
}
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMDOMCONSTRUCTOR
nsresult Construct(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, PRUint32 argc, jsval *argv,
@@ -4941,18 +4946,19 @@ private:
(aNameStruct->mType == nsGlobalNameStruct::eTypeClassConstructor &&
FindConstructorContractID(aNameStruct->mDOMClassInfoID)) ||
(aNameStruct->mType == nsGlobalNameStruct::eTypeExternalClassInfo &&
aNameStruct->mData->mConstructorCID) ||
aNameStruct->mType == nsGlobalNameStruct::eTypeExternalConstructor ||
aNameStruct->mType == nsGlobalNameStruct::eTypeExternalConstructorAlias;
}
- const PRUnichar *mClassName;
+ const PRUnichar* mClassName;
const PRPackedBool mConstructable;
+ nsWeakPtr mWeakOwner;
};
NS_IMPL_ADDREF(nsDOMConstructor)
NS_IMPL_RELEASE(nsDOMConstructor)
NS_INTERFACE_MAP_BEGIN(nsDOMConstructor)
NS_INTERFACE_MAP_ENTRY(nsIDOMDOMConstructor)
NS_INTERFACE_MAP_ENTRY(nsISupports)
if (aIID.Equals(NS_GET_IID(nsIClassInfo))) {
@@ -4989,17 +4995,17 @@ nsDOMConstructor::Construct(nsIXPConnect
const nsGlobalNameStruct *name_struct = GetNameStruct();
NS_ENSURE_TRUE(name_struct, NS_ERROR_FAILURE);
if (!IsConstructable(name_struct)) {
// ignore return value, we return JS_FALSE anyway
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
- return BaseStubConstructor(name_struct, cx, obj, argc, argv, vp);
+ return BaseStubConstructor(mWeakOwner, name_struct, cx, obj, argc, argv, vp);
}
nsresult
nsDOMConstructor::HasInstance(nsIXPConnectWrappedNative *wrapper,
JSContext * cx, JSObject * obj,
jsval v, PRBool *bp, PRBool *_retval)
{
@@ -5195,17 +5201,18 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
if (name_struct->mType == nsGlobalNameStruct::eTypeInterface) {
// We're resolving a name of a DOM interface for which there is no
// direct DOM class, create a constructor object...
nsRefPtr<nsDOMConstructor> constructor =
new nsDOMConstructor(reinterpret_cast<PRUnichar *>
(::JS_GetStringChars(str)),
- name_struct);
+ name_struct,
+ static_cast<nsPIDOMWindow*>(aWin));
if (!constructor) {
return NS_ERROR_OUT_OF_MEMORY;
}
PRBool doSecurityCheckInAddProperty = sDoSecurityCheckInAddProperty;
sDoSecurityCheckInAddProperty = PR_FALSE;
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
@@ -5257,17 +5264,18 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
} else if (alias_struct->mType == nsGlobalNameStruct::eTypeExternalClassInfo) {
ci_data = alias_struct->mData;
}
}
const PRUnichar *name = reinterpret_cast<PRUnichar *>
(::JS_GetStringChars(str));
nsRefPtr<nsDOMConstructor> constructor =
- new nsDOMConstructor(name, name_struct);
+ new nsDOMConstructor(name, name_struct,
+ static_cast<nsPIDOMWindow*>(aWin));
if (!constructor) {
return NS_ERROR_OUT_OF_MEMORY;
}
PRBool doSecurityCheckInAddProperty = sDoSecurityCheckInAddProperty;
sDoSecurityCheckInAddProperty = PR_FALSE;
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
@@ -5478,17 +5486,18 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
*did_resolve = PR_TRUE;
return NS_OK;
}
if (name_struct->mType == nsGlobalNameStruct::eTypeExternalConstructor) {
nsRefPtr<nsDOMConstructor> constructor =
- new nsDOMConstructor(class_name, name_struct);
+ new nsDOMConstructor(class_name, name_struct,
+ static_cast<nsPIDOMWindow*>(aWin));
if (!constructor) {
return NS_ERROR_OUT_OF_MEMORY;
}
jsval val;
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = WrapNative(cx, obj, constructor, NS_GET_IID(nsIDOMDOMConstructor),
&val, getter_AddRefs(holder));
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -277,17 +277,17 @@ static void Shutdown();
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPath1SchemeProcessor)
// Factory Constructor
NS_GENERIC_FACTORY_CONSTRUCTOR(txMozillaXSLTProcessor)
NS_GENERIC_AGGREGATED_CONSTRUCTOR_INIT(nsXPathEvaluator, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(txNodeSetAdaptor, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMSerializer)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsXMLHttpRequest)
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsXMLHttpRequest, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMParser)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsDOMStorageManager,
nsDOMStorageManager::GetInstance)
//-----------------------------------------------------------------------------
// Per bug 209804, it is necessary to observe the "xpcom-shutdown" event and
// perform shutdown of the layout modules at that time instead of waiting for