# HG changeset patch # User wfernandom2004@gmail.com # Date 1276774072 -10800 # Node ID 2183ae24152abd6b38217b52cdb91ae574d2bd6d # Parent 979b65e6b73ed61a5d4ead6b8bc5596c08f54af7 Bug 472529, websockets (content patch) diff --git a/content/base/public/Makefile.in b/content/base/public/Makefile.in --- a/content/base/public/Makefile.in +++ b/content/base/public/Makefile.in @@ -78,6 +78,7 @@ nsLineBreaker.h \ nsReferencedElement.h \ nsXMLNameSpaceMap.h \ +nsDOMEventTargetWrapperCache.h \ $(NULL) EXPORTS_NAMESPACES = mozilla/dom diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -129,6 +129,7 @@ class nsIMIMEHeaderParam; class nsIObserver; class nsPresContext; +class nsIChannel; #ifndef have_PrefChangedFunc_typedef typedef int (*PR_CALLBACK PrefChangedFunc)(const char *, void *); @@ -1524,6 +1525,8 @@ static already_AddRefed GetDocumentFromScriptContext(nsIScriptContext *aScriptContext); + static PRBool CheckMayLoad(nsIPrincipal* aPrincipal, nsIChannel* aChannel); + /** * The method checks whether the caller can access native anonymous content. * If there is no JS in the stack or privileged JS is running, this diff --git a/content/base/public/nsDOMEventTargetWrapperCache.h b/content/base/public/nsDOMEventTargetWrapperCache.h new file mode 100644 --- /dev/null +++ b/content/base/public/nsDOMEventTargetWrapperCache.h @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 : */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Wellington Fernando de Macedo. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Wellington Fernando de Macedo (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsDOMEventTargetWrapperCache_h__ +#define nsDOMEventTargetWrapperCache_h__ + +#include "nsDOMEventTargetHelper.h" +#include "nsWrapperCache.h" +#include "nsIScriptContext.h" + + +// Base class intended to be used for objets like XMLHttpRequest, +// EventSource and WebSocket. + +class nsDOMEventTargetWrapperCache : public nsDOMEventTargetHelper, + public nsWrapperCache +{ +public: + NS_DECL_ISUPPORTS_INHERITED + + class NS_CYCLE_COLLECTION_INNERCLASS + : public NS_CYCLE_COLLECTION_CLASSNAME(nsDOMEventTargetHelper) + { + NS_IMETHOD RootAndUnlinkJSObjects(void *p); + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(nsDOMEventTargetWrapperCache, + nsDOMEventTargetHelper) + NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure); + }; + NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE + + void GetParentObject(nsIScriptGlobalObject **aParentObject) + { + if (mOwner) { + CallQueryInterface(mOwner, aParentObject); + } + else { + *aParentObject = nsnull; + } + } + + static nsDOMEventTargetWrapperCache* FromSupports(nsISupports* aSupports) + { + nsPIDOMEventTarget* target = + static_cast(aSupports); +#ifdef DEBUG + { + nsCOMPtr target_qi = + do_QueryInterface(aSupports); + + // If this assertion fires the QI implementation for the object in + // question doesn't use the nsPIDOMEventTarget pointer as the + // nsISupports pointer. That must be fixed, or we'll crash... + NS_ASSERTION(target_qi == target, "Uh, fix QI!"); + } +#endif + + return static_cast(target); + } + +protected: + nsDOMEventTargetWrapperCache() : nsDOMEventTargetHelper(), nsWrapperCache() {} + virtual ~nsDOMEventTargetWrapperCache(); +}; + +#endif // nsDOMEventTargetWrapperCache_h__ diff --git a/content/base/src/Makefile.in b/content/base/src/Makefile.in --- a/content/base/src/Makefile.in +++ b/content/base/src/Makefile.in @@ -91,6 +91,7 @@ nsDOMAttribute.cpp \ nsDOMAttributeMap.cpp \ nsDOMDocumentType.cpp \ + nsDOMEventTargetWrapperCache.cpp \ nsDOMFile.cpp \ nsDOMFileReader.cpp \ nsDOMLists.cpp \ diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -5091,6 +5091,17 @@ return doc; } +/* static */ +PRBool +nsContentUtils::CheckMayLoad(nsIPrincipal* aPrincipal, nsIChannel* aChannel) +{ + nsCOMPtr channelURI; + nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(channelURI)); + NS_ENSURE_SUCCESS(rv, PR_FALSE); + + return NS_SUCCEEDED(aPrincipal->CheckMayLoad(channelURI, PR_FALSE)); +} + nsContentTypeParser::nsContentTypeParser(const nsAString& aString) : mString(aString), mService(nsnull) { diff --git a/content/base/src/nsDOMEventTargetWrapperCache.cpp b/content/base/src/nsDOMEventTargetWrapperCache.cpp new file mode 100644 --- /dev/null +++ b/content/base/src/nsDOMEventTargetWrapperCache.cpp @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 : */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Wellington Fernando de Macedo. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Wellington Fernando de Macedo (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsContentUtils.h" +#include "nsDOMEventTargetWrapperCache.h" +#include "nsIDocument.h" + +nsDOMEventTargetWrapperCache::~nsDOMEventTargetWrapperCache() +{ + nsISupports *supports = static_cast(this); + nsContentUtils::ReleaseWrapper(supports, this); +} + +NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMEventTargetWrapperCache) + +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMEventTargetWrapperCache) + NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER +NS_IMPL_CYCLE_COLLECTION_TRACE_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMEventTargetWrapperCache, + nsDOMEventTargetHelper) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsDOMEventTargetWrapperCache) + NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER +NS_IMPL_CYCLE_COLLECTION_ROOT_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMEventTargetWrapperCache, + nsDOMEventTargetHelper) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMEventTargetWrapperCache) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY +NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper) + +NS_IMPL_ADDREF_INHERITED(nsDOMEventTargetWrapperCache, nsDOMEventTargetHelper) +NS_IMPL_RELEASE_INHERITED(nsDOMEventTargetWrapperCache, nsDOMEventTargetHelper) diff --git a/content/base/src/nsXMLHttpRequest.cpp b/content/base/src/nsXMLHttpRequest.cpp --- a/content/base/src/nsXMLHttpRequest.cpp +++ b/content/base/src/nsXMLHttpRequest.cpp @@ -503,21 +503,10 @@ ///////////////////////////////////////////// -nsXHREventTarget::~nsXHREventTarget() -{ - nsISupports *supports = static_cast(this); - nsContentUtils::ReleaseWrapper(supports, this); -} - NS_IMPL_CYCLE_COLLECTION_CLASS(nsXHREventTarget) -NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsXHREventTarget) - NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER -NS_IMPL_CYCLE_COLLECTION_TRACE_END - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXHREventTarget, - nsDOMEventTargetHelper) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS + nsDOMEventTargetWrapperCache) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnLoadListener) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnAbortListener) @@ -525,12 +514,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnProgressListener) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END -NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsXHREventTarget) - NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER -NS_IMPL_CYCLE_COLLECTION_ROOT_END - NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXHREventTarget, - nsDOMEventTargetHelper) + nsDOMEventTargetWrapperCache) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnLoadListener) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnAbortListener) @@ -539,12 +524,11 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXHREventTarget) - NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequestEventTarget) -NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper) - -NS_IMPL_ADDREF_INHERITED(nsXHREventTarget, nsDOMEventTargetHelper) -NS_IMPL_RELEASE_INHERITED(nsXHREventTarget, nsDOMEventTargetHelper) +NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetWrapperCache) + +NS_IMPL_ADDREF_INHERITED(nsXHREventTarget, nsDOMEventTargetWrapperCache) +NS_IMPL_RELEASE_INHERITED(nsXHREventTarget, nsDOMEventTargetWrapperCache) NS_IMETHODIMP nsXHREventTarget::GetOnload(nsIDOMEventListener** aOnLoad) @@ -1566,36 +1550,20 @@ return httpChannel; } -inline PRBool -IsSystemPrincipal(nsIPrincipal* aPrincipal) -{ - PRBool isSystem = PR_FALSE; - nsContentUtils::GetSecurityManager()-> - IsSystemPrincipal(aPrincipal, &isSystem); - return isSystem; -} - -static PRBool -CheckMayLoad(nsIPrincipal* aPrincipal, nsIChannel* aChannel) -{ - NS_ASSERTION(!IsSystemPrincipal(aPrincipal), "Shouldn't get here!"); - - nsCOMPtr channelURI; - nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(channelURI)); - NS_ENSURE_SUCCESS(rv, PR_FALSE); - - return NS_SUCCEEDED(aPrincipal->CheckMayLoad(channelURI, PR_FALSE)); -} - nsresult nsXMLHttpRequest::CheckChannelForCrossSiteRequest(nsIChannel* aChannel) { nsresult rv; - // First check if this is a same-origin request, or if cross-site requests - // are enabled. - if ((mState & XML_HTTP_REQUEST_XSITEENABLED) || - CheckMayLoad(mPrincipal, aChannel)) { + // First check if cross-site requests are enabled + if ((mState & XML_HTTP_REQUEST_XSITEENABLED)) { + return NS_OK; + } + + // or if this is a same-origin request. + NS_ASSERTION(!nsContentUtils::IsSystemPrincipal(mPrincipal), + "Shouldn't get here!"); + if (nsContentUtils::CheckMayLoad(mPrincipal, aChannel)) { return NS_OK; } @@ -1773,7 +1741,7 @@ if (NS_FAILED(rv)) return rv; // Check if we're doing a cross-origin request. - if (IsSystemPrincipal(mPrincipal)) { + if (nsContentUtils::IsSystemPrincipal(mPrincipal)) { // Chrome callers are always allowed to read from different origins. mState |= XML_HTTP_REQUEST_XSITEENABLED; } @@ -1930,7 +1898,7 @@ NS_ENSURE_TRUE(channel, NS_ERROR_UNEXPECTED); nsCOMPtr documentPrincipal = mPrincipal; - if (IsSystemPrincipal(documentPrincipal)) { + if (nsContentUtils::IsSystemPrincipal(documentPrincipal)) { // Don't give this document the system principal. We need to keep track of // mPrincipal being system because we use it for various security checks // that should be passing, but the document data shouldn't get a system @@ -2399,7 +2367,7 @@ if (httpChannel) { httpChannel->GetRequestMethod(method); // If GET, method name will be uppercase - if (!IsSystemPrincipal(mPrincipal)) { + if (!nsContentUtils::IsSystemPrincipal(mPrincipal)) { nsCOMPtr codebase; mPrincipal->GetURI(getter_AddRefs(codebase)); diff --git a/content/base/src/nsXMLHttpRequest.h b/content/base/src/nsXMLHttpRequest.h --- a/content/base/src/nsXMLHttpRequest.h +++ b/content/base/src/nsXMLHttpRequest.h @@ -67,7 +67,7 @@ #include "nsITimer.h" #include "nsIPrivateDOMEvent.h" #include "nsDOMProgressEvent.h" -#include "nsDOMEventTargetHelper.h" +#include "nsDOMEventTargetWrapperCache.h" class nsILoadGroup; @@ -137,57 +137,18 @@ PRCList mList; }; -class nsXHREventTarget : public nsDOMEventTargetHelper, - public nsIXMLHttpRequestEventTarget, - public nsWrapperCache +class nsXHREventTarget : public nsDOMEventTargetWrapperCache, + public nsIXMLHttpRequestEventTarget { public: - virtual ~nsXHREventTarget(); + virtual ~nsXHREventTarget() {} NS_DECL_ISUPPORTS_INHERITED - - class NS_CYCLE_COLLECTION_INNERCLASS - : public NS_CYCLE_COLLECTION_CLASSNAME(nsDOMEventTargetHelper) - { - NS_IMETHOD RootAndUnlinkJSObjects(void *p); - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(nsXHREventTarget, - nsDOMEventTargetHelper) - NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure); - }; - NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE - + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXHREventTarget, + nsDOMEventTargetWrapperCache) NS_DECL_NSIXMLHTTPREQUESTEVENTTARGET NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::) NS_FORWARD_NSIDOMNSEVENTTARGET(nsDOMEventTargetHelper::) - void GetParentObject(nsIScriptGlobalObject **aParentObject) - { - if (mOwner) { - CallQueryInterface(mOwner, aParentObject); - } - else { - *aParentObject = nsnull; - } - } - - static nsXHREventTarget* FromSupports(nsISupports* aSupports) - { - nsPIDOMEventTarget* target = - static_cast(aSupports); -#ifdef DEBUG - { - nsCOMPtr target_qi = - do_QueryInterface(aSupports); - - // If this assertion fires the QI implementation for the object in - // question doesn't use the nsPIDOMEventTarget pointer as the - // nsISupports pointer. That must be fixed, or we'll crash... - NS_ASSERTION(target_qi == target, "Uh, fix QI!"); - } -#endif - - return static_cast(target); - } - protected: nsRefPtr mOnLoadListener; nsRefPtr mOnErrorListener; diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -68,6 +68,7 @@ #include "nsCSSValue.h" #include "nsIRunnable.h" #include "nsThreadUtils.h" +#include "nsDOMEventTargetWrapperCache.h" // General helper includes #include "nsGlobalWindow.h" @@ -7689,7 +7690,8 @@ nsEventTargetSH::PreCreate(nsISupports *nativeObj, JSContext *cx, JSObject *globalObj, JSObject **parentObj) { - nsXHREventTarget *target = nsXHREventTarget::FromSupports(nativeObj); + nsDOMEventTargetWrapperCache *target = + nsDOMEventTargetWrapperCache::FromSupports(nativeObj); nsCOMPtr native_parent; target->GetParentObject(getter_AddRefs(native_parent)); @@ -7715,7 +7717,8 @@ void nsEventTargetSH::PreserveWrapper(nsISupports *aNative) { - nsXHREventTarget *target = nsXHREventTarget::FromSupports(aNative); + nsDOMEventTargetWrapperCache *target = + nsDOMEventTargetWrapperCache::FromSupports(aNative); nsContentUtils::PreserveWrapper(aNative, target); }