Move the safe vs unsafe about: distinction out of the security manager and into

nsIAboutModule implementations.  Bug 337746, r=dveditz, sr=darin
This commit is contained in:
bzbarsky%mit.edu 2006-06-19 21:02:12 +00:00
parent 31fbfa9477
commit 9509962b32
21 changed files with 556 additions and 242 deletions

View File

@ -1201,25 +1201,6 @@ nsScriptSecurityManager::GetBaseURIScheme(nsIURI* aURI,
rv = uri->GetScheme(aScheme);
if (NS_FAILED(rv)) return rv;
//-- if aURI is an about uri, distinguish 'safe' and 'unsafe' about URIs
if(aScheme.EqualsLiteral("about"))
{
nsCAutoString path;
rv = NS_GetAboutModuleName(uri, path);
NS_ENSURE_SUCCESS(rv, rv);
if (path.EqualsLiteral("blank") ||
path.EqualsLiteral("mozilla") ||
path.EqualsLiteral("logo") ||
path.EqualsLiteral("license") ||
path.EqualsLiteral("licence") ||
path.EqualsLiteral("credits") ||
path.EqualsLiteral("neterror"))
{
aScheme = NS_LITERAL_CSTRING("about safe");
return NS_OK;
}
}
return NS_OK;
}
@ -1334,8 +1315,8 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
{ "news", AllowProtocol },
{ "javascript", AllowProtocol },
{ "ftp", AllowProtocol },
{ "about safe", AllowProtocol },
{ "about", ChromeProtocol },
{ "moz-safe-about", AllowProtocol },
{ "about", DenyProtocol },
{ "mailto", AllowProtocol },
{ "aim", AllowProtocol },
{ "data", AllowProtocol },
@ -1365,6 +1346,8 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
case PrefControlled:
{
// resource: and chrome: are equivalent, securitywise
// That's bogus!! Fix this. But watch out for
// the view-source stylesheet?
if (sourceScheme.EqualsLiteral("chrome") ||
sourceScheme.EqualsLiteral("resource"))
return NS_OK;
@ -1390,6 +1373,8 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
if (aFlags & nsIScriptSecurityManager::ALLOW_CHROME)
return NS_OK;
// resource: and chrome: are equivalent, securitywise
// That's bogus!! Fix this. But watch out for
// the view-source stylesheet?
if (sourceScheme.EqualsLiteral("chrome") ||
sourceScheme.EqualsLiteral("resource"))
return NS_OK;

View File

@ -61,6 +61,10 @@ AboutHandler.prototype =
var ext_channel = ioService.newChannelFromURI(ext_uri);
return ext_channel;
}
getURIFlags : function safeForUntrustedContent(aURI) {
return 0;
}
};

View File

@ -621,6 +621,13 @@ nsMetricsService::NewChannel(nsIURI *uri, nsIChannel **result)
return NS_OK;
}
NS_IMETHODIMP
nsMetricsService::GetURIFlags(nsIURI *aURI, PRUint32 *result)
{
*result = 0;
return NS_OK;
}
NS_IMETHODIMP
nsMetricsService::OnStartRequest(nsIRequest *request, nsISupports *context)
{

View File

@ -63,3 +63,6 @@ class AboutPython:
#channel.contentType = "text/html"
channel.contentStream = istream
return channel
def getURIFlags(self, aURI):
return 0;

View File

@ -77,6 +77,7 @@ CPPSRCS = \
nsRequestObserverProxy.cpp \
nsSimpleStreamListener.cpp \
nsSimpleURI.cpp \
nsSimpleNestedURI.cpp \
nsStandardURL.cpp \
nsSocketTransport2.cpp \
nsSocketTransportService2.cpp \

View File

@ -0,0 +1,161 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** 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
* the Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Boris Zbarsky <bzbarsky@mit.edu> (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 "nsSimpleNestedURI.h"
#include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h"
#include "nsNetUtil.h"
NS_IMPL_ISUPPORTS_INHERITED1(nsSimpleNestedURI, nsSimpleURI, nsINestedURI)
nsSimpleNestedURI::nsSimpleNestedURI(nsIURI* innerURI)
: nsSimpleURI(nsnull),
mInnerURI(innerURI)
{
NS_ASSERTION(innerURI, "Must have inner URI");
NS_TryToSetImmutable(innerURI);
}
// nsISerializable
NS_IMETHODIMP
nsSimpleNestedURI::Read(nsIObjectInputStream* aStream)
{
nsresult rv = nsSimpleURI::Read(aStream);
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(!mMutable, "How did that happen?");
rv = aStream->ReadObject(PR_TRUE, getter_AddRefs(mInnerURI));
if (NS_FAILED(rv)) return rv;
NS_TryToSetImmutable(mInnerURI);
return rv;
}
NS_IMETHODIMP
nsSimpleNestedURI::Write(nsIObjectOutputStream* aStream)
{
nsCOMPtr<nsISerializable> serializable = do_QueryInterface(mInnerURI);
if (!serializable) {
// We can't serialize ourselves
return NS_ERROR_NOT_AVAILABLE;
}
nsresult rv = nsSimpleURI::Write(aStream);
if (NS_FAILED(rv)) return rv;
rv = aStream->WriteCompoundObject(mInnerURI, NS_GET_IID(nsIURI),
PR_TRUE);
return rv;
}
// nsINestedURI
NS_IMETHODIMP
nsSimpleNestedURI::GetInnerURI(nsIURI** uri)
{
NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
return NS_EnsureSafeToReturn(mInnerURI, uri);
}
NS_IMETHODIMP
nsSimpleNestedURI::GetInnermostURI(nsIURI** uri)
{
return NS_ImplGetInnermostURI(this, uri);
}
// nsIURI overrides
NS_IMETHODIMP
nsSimpleNestedURI::Equals(nsIURI* other, PRBool *result)
{
*result = PR_FALSE;
NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
if (other) {
PRBool correctScheme;
nsresult rv = other->SchemeIs(mScheme.get(), &correctScheme);
NS_ENSURE_SUCCESS(rv, rv);
if (correctScheme) {
nsCOMPtr<nsINestedURI> nest = do_QueryInterface(other);
if (nest) {
nsCOMPtr<nsIURI> otherInner;
rv = nest->GetInnerURI(getter_AddRefs(otherInner));
NS_ENSURE_SUCCESS(rv, rv);
return otherInner->Equals(mInnerURI, result);
}
}
}
return NS_OK;
}
/* virtual */ nsSimpleURI*
nsSimpleNestedURI::StartClone()
{
NS_ENSURE_TRUE(mInnerURI, nsnull);
nsCOMPtr<nsIURI> innerClone;
nsresult rv = mInnerURI->Clone(getter_AddRefs(innerClone));
if (NS_FAILED(rv)) {
return nsnull;
}
nsSimpleNestedURI* url = new nsSimpleNestedURI(innerClone);
if (url) {
url->SetMutable(PR_FALSE);
}
return url;
}
// nsIClassInfo overrides
NS_IMETHODIMP
nsSimpleNestedURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
{
static NS_DEFINE_CID(kSimpleNestedURICID, NS_SIMPLENESTEDURI_CID);
*aClassIDNoAlloc = kSimpleNestedURICID;
return NS_OK;
}

View File

@ -0,0 +1,92 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** 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
* the Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Boris Zbarsky <bzbarsky@mit.edu> (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 ***** */
/**
* URI class to be used for cases when a simple URI actually resolves to some
* other sort of URI, with the latter being what's loaded when the load
* happens. All objects of this class should always be immutable, so that the
* inner URI and this URI don't get out of sync. The Clone() implementation
* will guarantee this for the clone, but it's up to the protocol handlers
* creating these URIs to ensure that in the first place. The innerURI passed
* to this URI will be set immutable if possible.
*/
#ifndef nsSimpleNestedURI_h__
#define nsSimpleNestedURI_h__
#include "nsCOMPtr.h"
#include "nsSimpleURI.h"
#include "nsINestedURI.h"
class nsSimpleNestedURI : public nsSimpleURI,
public nsINestedURI
{
public:
// To be used by deserialization only. Leaves this object in an
// uninitialized state that will throw on most accesses.
nsSimpleNestedURI()
: nsSimpleURI(nsnull)
{
}
// Constructor that should generally be used when constructing an object of
// this class with |operator new|.
nsSimpleNestedURI(nsIURI* innerURI);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSINESTEDURI
// Overrides for various methods nsSimpleURI implements follow.
// nsIURI overrides
NS_IMETHOD Equals(nsIURI* other, PRBool *result);
virtual nsSimpleURI* StartClone();
// nsISerializable overrides
NS_IMETHOD Read(nsIObjectInputStream* aStream);
NS_IMETHOD Write(nsIObjectOutputStream* aStream);
// Override the nsIClassInfo method GetClassIDNoAlloc to make sure our
// nsISerializable impl works right.
NS_IMETHOD GetClassIDNoAlloc(nsCID *aClassIDNoAlloc);
protected:
nsCOMPtr<nsIURI> mInnerURI;
};
#endif /* nsSimpleNestedURI_h__ */

View File

@ -113,6 +113,16 @@
{0x8c, 0xd0, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
// component inheriting from the simple URI component and also
// implementing nsINestedURI.
#define NS_SIMPLENESTEDURI_CID \
{ /* 56388dad-287b-4240-a785-85c394012503 */ \
0x56388dad, \
0x287b, \
0x4240, \
{ 0xa7, 0x85, 0x85, 0xc3, 0x94, 0x01, 0x25, 0x03 } \
}
// component implementing nsIStandardURL, nsIURI, nsIURL, nsISerializable,
// and nsIClassInfo.
#define NS_STANDARDURL_CLASSNAME \
@ -601,6 +611,30 @@
{0xae, 0xa8, 0x8f, 0xcc, 0x07, 0x93, 0xe9, 0x7f} \
}
/******************************************************************************
* netwerk/protocol/about/ classes
*/
#define NS_ABOUTPROTOCOLHANDLER_CLASSNAME \
"About Protocol Handler"
#define NS_ABOUTPROTOCOLHANDLER_CID \
{ /* 9e3b6c90-2f75-11d3-8cd0-0060b0fc14a3 */ \
0x9e3b6c90, \
0x2f75, \
0x11d3, \
{0x8c, 0xd0, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
#define NS_SAFEABOUTPROTOCOLHANDLER_CLASSNAME \
"Safe About Protocol Handler"
#define NS_SAFEABOUTPROTOCOLHANDLER_CID \
{ /* 1423e739-782c-4081-b5d8-fe6fba68c0ef */ \
0x1423e739, \
0x782c, \
0x4081, \
{0xb5, 0xd8, 0xfe, 0x6f, 0xba, 0x68, 0xc0, 0xef} \
}
/******************************************************************************
* netwerk/dns/ classes
*/

View File

@ -47,6 +47,7 @@
#include "nsSocketProviderService.h"
#include "nscore.h"
#include "nsSimpleURI.h"
#include "nsSimpleNestedURI.h"
#include "nsLoadGroup.h"
#include "nsStreamLoader.h"
#include "nsUnicharStreamLoader.h"
@ -173,6 +174,8 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsCookieService, nsCookieService::GetSi
// about:blank is mandatory
#include "nsAboutProtocolHandler.h"
#include "nsAboutBlank.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAboutProtocolHandler)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSafeAboutProtocolHandler)
#ifdef NECKO_PROTOCOL_about
// about
@ -227,7 +230,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsGopherHandler)
#ifdef NECKO_PROTOCOL_viewsource
#include "nsViewSourceHandler.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsViewSourceHandler)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsViewSourceURI)
#endif
#ifdef NECKO_PROTOCOL_data
@ -251,6 +253,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsStandardURL)
NS_GENERIC_AGGREGATED_CONSTRUCTOR(nsSimpleURI)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSimpleNestedURI)
///////////////////////////////////////////////////////////////////////////////
#include "nsIDNService.h"
@ -650,6 +654,10 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
NS_SIMPLEURI_CID,
NS_SIMPLEURI_CONTRACTID,
nsSimpleURIConstructor },
{ "Simple Nested URI",
NS_SIMPLENESTEDURI_CID,
nsnull,
nsSimpleNestedURIConstructor },
{ NS_ASYNCSTREAMCOPIER_CLASSNAME,
NS_ASYNCSTREAMCOPIER_CID,
NS_ASYNCSTREAMCOPIER_CONTRACTID,
@ -974,10 +982,15 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
#endif
// from netwerk/protocol/about (about:blank is mandatory):
{ "About Protocol Handler",
{ NS_ABOUTPROTOCOLHANDLER_CLASSNAME,
NS_ABOUTPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "about",
nsAboutProtocolHandler::Create
nsAboutProtocolHandlerConstructor
},
{ NS_SAFEABOUTPROTOCOLHANDLER_CLASSNAME,
NS_SAFEABOUTPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "safe-about",
nsSafeAboutProtocolHandlerConstructor
},
{ "about:blank",
NS_ABOUT_BLANK_MODULE_CID,
@ -1109,11 +1122,6 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "view-source",
nsViewSourceHandlerConstructor
},
{ "The ViewSource URI",
NS_VIEWSOURCEURI_CID,
nsnull,
nsViewSourceURIConstructor
},
#endif
#if defined(XP_WIN) && !defined(WINCE)

View File

@ -40,7 +40,7 @@
interface nsIURI;
interface nsIChannel;
[scriptable, uuid(692303c0-2f83-11d3-8cd0-0060b0fc14a3)]
[scriptable, uuid(9575693c-60d9-4332-b6b8-6c29289339cb)]
interface nsIAboutModule : nsISupports
{
/**
@ -49,6 +49,21 @@ interface nsIAboutModule : nsISupports
* @param aURI the uri of the new channel
*/
nsIChannel newChannel(in nsIURI aURI);
/**
* A flag that indicates whether a URI is safe for untrusted
* content. If it is, web pages and so forth will be allowed to
* link to this about: URI. Otherwise, only chrome will be able
* to link to it.
*/
const unsigned long URI_SAFE_FOR_UNTRUSTED_CONTENT = (1 << 0);
/**
* A method to get the flags that apply to a given about: URI. The URI
* passed in is guaranteed to be one of the URIs that this module
* registered to deal with.
*/
unsigned long getURIFlags(in nsIURI aURI);
};
%{C++

View File

@ -63,6 +63,8 @@ CPPSRCS = \
nsAboutRedirector.cpp \
$(NULL)
LOCAL_INCLUDES=-I$(srcdir)/../../../base/src
# we don't want the shared lib, but we want to force the creation of a
# static lib.
FORCE_STATIC_LIB = 1

View File

@ -66,6 +66,13 @@ nsAboutBlank::NewChannel(nsIURI *aURI, nsIChannel **result)
return rv;
}
NS_IMETHODIMP
nsAboutBlank::GetURIFlags(nsIURI *aURI, PRUint32 *result)
{
*result = nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT;
return NS_OK;
}
NS_METHOD
nsAboutBlank::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{

View File

@ -157,6 +157,13 @@ nsAboutBloat::NewChannel(nsIURI *aURI, nsIChannel **result)
return rv;
}
NS_IMETHODIMP
nsAboutBloat::GetURIFlags(nsIURI *aURI, PRUint32 *result)
{
*result = 0;
return NS_OK;
}
NS_METHOD
nsAboutBloat::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{

View File

@ -139,6 +139,12 @@ nsAboutCache::NewChannel(nsIURI *aURI, nsIChannel **result)
return rv;
}
NS_IMETHODIMP
nsAboutCache::GetURIFlags(nsIURI *aURI, PRUint32 *result)
{
*result = 0;
return NS_OK;
}
NS_IMETHODIMP
nsAboutCache::VisitDevice(const char *deviceID,

View File

@ -129,6 +129,13 @@ nsAboutCacheEntry::NewChannel(nsIURI *uri, nsIChannel **result)
NS_LITERAL_CSTRING("utf-8"));
}
NS_IMETHODIMP
nsAboutCacheEntry::GetURIFlags(nsIURI *aURI, PRUint32 *result)
{
*result = 0;
return NS_OK;
}
//-----------------------------------------------------------------------------
// nsAboutCacheEntry

View File

@ -48,45 +48,15 @@
#include "nsNetCID.h"
#include "nsAboutProtocolUtils.h"
#include "nsNetError.h"
#include "nsNetUtil.h"
#include "nsSimpleNestedURI.h"
static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
////////////////////////////////////////////////////////////////////////////////
nsAboutProtocolHandler::nsAboutProtocolHandler()
{
}
nsresult
nsAboutProtocolHandler::Init()
{
return NS_OK;
}
nsAboutProtocolHandler::~nsAboutProtocolHandler()
{
}
NS_IMPL_ISUPPORTS1(nsAboutProtocolHandler, nsIProtocolHandler)
NS_METHOD
nsAboutProtocolHandler::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsAboutProtocolHandler* ph = new nsAboutProtocolHandler();
if (ph == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(ph);
nsresult rv = ph->Init();
if (NS_SUCCEEDED(rv)) {
rv = ph->QueryInterface(aIID, aResult);
}
NS_RELEASE(ph);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsIProtocolHandler methods:
@ -117,36 +87,67 @@ nsAboutProtocolHandler::NewURI(const nsACString &aSpec,
nsIURI *aBaseURI,
nsIURI **result)
{
*result = nsnull;
nsresult rv;
nsIURI* url;
rv = CallCreateInstance(kSimpleURICID, &url);
// Use a simple URI to parse out some stuff first
nsCOMPtr<nsIURI> url = do_CreateInstance(kSimpleURICID, &rv);
if (NS_FAILED(rv)) return rv;
rv = url->SetSpec(aSpec);
if (NS_FAILED(rv)) {
NS_RELEASE(url);
return rv;
}
*result = url;
return rv;
// Unfortunately, people create random about: URIs that don't correspond to
// about: modules... Since those URIs will never open a channel, might as
// well consider them unsafe for better perf, and just in case.
PRBool isSafe = PR_FALSE;
nsCOMPtr<nsIAboutModule> aboutMod;
rv = GetModuleForURI(url, getter_AddRefs(aboutMod));
if (NS_SUCCEEDED(rv)) {
// The standard return case
PRUint32 flags;
rv = aboutMod->GetURIFlags(url, &flags);
NS_ENSURE_SUCCESS(rv, rv);
isSafe =
((flags & nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT) != 0);
}
if (isSafe) {
// We need to indicate that this baby is safe. Use an inner
// URI that no one but the security manager will see.
nsCOMPtr<nsIURI> inner;
rv = NS_NewURI(getter_AddRefs(inner), "moz-safe-about:x");
NS_ENSURE_SUCCESS(rv, rv);
nsSimpleNestedURI* outer = new nsSimpleNestedURI(inner);
NS_ENSURE_TRUE(outer, NS_ERROR_OUT_OF_MEMORY);
// Take a ref to it in the COMPtr we plan to return
url = outer;
rv = outer->SetSpec(aSpec);
NS_ENSURE_SUCCESS(rv, rv);
}
// We don't want to allow mutation, since it would allow safe and
// unsafe URIs to change into each other...
NS_TryToSetImmutable(url);
url.swap(*result);
return NS_OK;
}
NS_IMETHODIMP
nsAboutProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
{
NS_ENSURE_ARG_POINTER(uri);
// about:what you ask?
nsresult rv;
nsCAutoString contractID;
rv = NS_GetAboutModuleName(uri, contractID);
if (NS_FAILED(rv)) return rv;
// look up a handler to deal with "what"
contractID.Insert(NS_LITERAL_CSTRING(NS_ABOUT_MODULE_CONTRACTID_PREFIX), 0);
nsCOMPtr<nsIAboutModule> aboutMod(do_GetService(contractID.get(), &rv));
nsCOMPtr<nsIAboutModule> aboutMod;
nsresult rv = GetModuleForURI(uri, getter_AddRefs(aboutMod));
if (NS_SUCCEEDED(rv)) {
// The standard return case:
return aboutMod->NewChannel(uri, result);
@ -170,4 +171,87 @@ nsAboutProtocolHandler::AllowPort(PRInt32 port, const char *scheme, PRBool *_ret
*_retval = PR_FALSE;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
/* static */
nsresult
nsAboutProtocolHandler::GetModuleForURI(nsIURI* uri, nsIAboutModule** module)
{
NS_PRECONDITION(uri, "Must have URI");
nsresult rv;
nsCAutoString contractID;
rv = NS_GetAboutModuleName(uri, contractID);
if (NS_FAILED(rv)) return rv;
// look up a handler to deal with "what"
contractID.Insert(NS_LITERAL_CSTRING(NS_ABOUT_MODULE_CONTRACTID_PREFIX), 0);
return CallGetService(contractID.get(), module);
}
////////////////////////////////////////////////////////////////////////////////
// Safe about protocol handler impl
NS_IMPL_ISUPPORTS1(nsSafeAboutProtocolHandler, nsIProtocolHandler)
// nsIProtocolHandler methods:
NS_IMETHODIMP
nsSafeAboutProtocolHandler::GetScheme(nsACString &result)
{
result.AssignLiteral("moz-safe-about");
return NS_OK;
}
NS_IMETHODIMP
nsSafeAboutProtocolHandler::GetDefaultPort(PRInt32 *result)
{
*result = -1; // no port for moz-safe-about: URLs
return NS_OK;
}
NS_IMETHODIMP
nsSafeAboutProtocolHandler::GetProtocolFlags(PRUint32 *result)
{
*result = URI_NORELATIVE | URI_NOAUTH;
return NS_OK;
}
NS_IMETHODIMP
nsSafeAboutProtocolHandler::NewURI(const nsACString &aSpec,
const char *aCharset, // ignore charset info
nsIURI *aBaseURI,
nsIURI **result)
{
nsresult rv;
nsCOMPtr<nsIURI> url = do_CreateInstance(kSimpleURICID, &rv);
if (NS_FAILED(rv)) return rv;
rv = url->SetSpec(aSpec);
if (NS_FAILED(rv)) {
return rv;
}
NS_TryToSetImmutable(url);
*result = nsnull;
url.swap(*result);
return rv;
}
NS_IMETHODIMP
nsSafeAboutProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
{
*result = nsnull;
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsSafeAboutProtocolHandler::AllowPort(PRInt32 port, const char *scheme, PRBool *_retval)
{
// don't override anything.
*_retval = PR_FALSE;
return NS_OK;
}

View File

@ -41,14 +41,7 @@
#include "nsIProtocolHandler.h"
class nsCString;
#define NS_ABOUTPROTOCOLHANDLER_CID \
{ /* 9e3b6c90-2f75-11d3-8cd0-0060b0fc14a3 */ \
0x9e3b6c90, \
0x2f75, \
0x11d3, \
{0x8c, 0xd0, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
class nsIAboutModule;
class nsAboutProtocolHandler : public nsIProtocolHandler
{
@ -59,13 +52,27 @@ public:
NS_DECL_NSIPROTOCOLHANDLER
// nsAboutProtocolHandler methods:
nsAboutProtocolHandler();
virtual ~nsAboutProtocolHandler();
nsAboutProtocolHandler() {}
virtual ~nsAboutProtocolHandler() {}
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsresult Init();
protected:
static nsresult GetModuleForURI(nsIURI* uri, nsIAboutModule** module);
};
class nsSafeAboutProtocolHandler : public nsIProtocolHandler
{
public:
NS_DECL_ISUPPORTS
// nsIProtocolHandler methods:
NS_DECL_NSIPROTOCOLHANDLER
// nsSafeAboutProtocolHandler methods:
nsSafeAboutProtocolHandler() {}
private:
~nsSafeAboutProtocolHandler() {}
};
#endif /* nsAboutProtocolHandler_h___ */

View File

@ -43,6 +43,7 @@
#include "plstr.h"
#include "nsIScriptSecurityManager.h"
#include "nsAboutProtocolUtils.h"
#include "nsSimpleNestedURI.h"
NS_IMPL_ISUPPORTS1(nsAboutRedirector, nsIAboutModule)
@ -129,6 +130,29 @@ nsAboutRedirector::NewChannel(nsIURI *aURI, nsIChannel **result)
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
nsAboutRedirector::GetURIFlags(nsIURI *aURI, PRUint32 *result)
{
NS_ENSURE_ARG_POINTER(aURI);
nsCAutoString name;
nsresult rv = NS_GetAboutModuleName(aURI, name);
NS_ENSURE_SUCCESS(rv, rv);
for (int i=0; i < kRedirTotal; i++)
{
if (name.EqualsASCII(kRedirMap[i].id))
{
*result = kRedirMap[i].dropChromePrivs ?
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT : 0;
return NS_OK;
}
}
NS_ERROR("nsAboutRedirector called for unknown case");
return NS_ERROR_ILLEGAL_VALUE;
}
NS_METHOD
nsAboutRedirector::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{

View File

@ -41,9 +41,7 @@
#include "nsViewSourceHandler.h"
#include "nsViewSourceChannel.h"
#include "nsNetUtil.h"
#include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h"
#include "nsIProgrammingLanguage.h"
#include "nsSimpleNestedURI.h"
#define VIEW_SOURCE "view-source"
@ -96,8 +94,6 @@ nsViewSourceHandler::NewURI(const nsACString &aSpec,
if (NS_FAILED(rv))
return rv;
NS_TryToSetImmutable(innerURI);
nsCAutoString asciiSpec;
rv = innerURI->GetAsciiSpec(asciiSpec);
if (NS_FAILED(rv))
@ -107,8 +103,9 @@ nsViewSourceHandler::NewURI(const nsACString &aSpec,
asciiSpec.Insert(VIEW_SOURCE ":", 0);
// We can't swap() from an nsRefPtr<nsViewSourceURI> to an nsIURI**, sadly.
nsViewSourceURI* ourURI = new nsViewSourceURI(innerURI);
// We can't swap() from an nsRefPtr<nsSimpleNestedURI> to an nsIURI**,
// sadly.
nsSimpleNestedURI* ourURI = new nsSimpleNestedURI(innerURI);
nsCOMPtr<nsIURI> uri = ourURI;
if (!uri)
return NS_ERROR_OUT_OF_MEMORY;
@ -118,7 +115,7 @@ nsViewSourceHandler::NewURI(const nsACString &aSpec,
return rv;
// Make the URI immutable so it's impossible to get it out of sync
// with mInnerURI.
// with its inner URI.
ourURI->SetMutable(PR_FALSE);
uri.swap(*aResult);
@ -151,98 +148,3 @@ nsViewSourceHandler::AllowPort(PRInt32 port, const char *scheme, PRBool *_retval
*_retval = PR_FALSE;
return NS_OK;
}
///////////////////////////////////////////////////////////////
// nsViewSourceURI implementation
static NS_DEFINE_CID(kViewSourceURICID, NS_VIEWSOURCEURI_CID);
NS_IMPL_ISUPPORTS_INHERITED1(nsViewSourceURI, nsSimpleURI, nsINestedURI)
// nsISerializable
NS_IMETHODIMP
nsViewSourceURI::Read(nsIObjectInputStream* aStream)
{
nsresult rv = nsSimpleURI::Read(aStream);
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(!mMutable, "How did that happen?");
// Our mPath is going to be ASCII; see nsViewSourceHandler::NewURI. So
// just using NS_NewURI with no charset is ok.
rv = NS_NewURI(getter_AddRefs(mInnerURI), mPath);
if (NS_FAILED(rv)) return rv;
NS_TryToSetImmutable(mInnerURI);
return rv;
}
// nsINestedURI
NS_IMETHODIMP
nsViewSourceURI::GetInnerURI(nsIURI** uri)
{
return NS_EnsureSafeToReturn(mInnerURI, uri);
}
NS_IMETHODIMP
nsViewSourceURI::GetInnermostURI(nsIURI** uri)
{
return NS_ImplGetInnermostURI(this, uri);
}
// nsIURI overrides
NS_IMETHODIMP
nsViewSourceURI::Equals(nsIURI* other, PRBool *result)
{
if (other) {
PRBool correctScheme;
nsresult rv = other->SchemeIs(VIEW_SOURCE, &correctScheme);
NS_ENSURE_SUCCESS(rv, rv);
if (correctScheme) {
nsCOMPtr<nsINestedURI> nest = do_QueryInterface(other);
if (nest) {
nsCOMPtr<nsIURI> otherInner;
rv = nest->GetInnerURI(getter_AddRefs(otherInner));
NS_ENSURE_SUCCESS(rv, rv);
return otherInner->Equals(mInnerURI, result);
}
}
}
*result = PR_FALSE;
return NS_OK;
}
/* virtual */ nsSimpleURI*
nsViewSourceURI::StartClone()
{
nsCOMPtr<nsIURI> innerClone;
nsresult rv = mInnerURI->Clone(getter_AddRefs(innerClone));
if (NS_FAILED(rv)) {
return nsnull;
}
NS_TryToSetImmutable(innerClone);
nsViewSourceURI* url = new nsViewSourceURI(innerClone);
if (url) {
url->SetMutable(PR_FALSE);
}
return url;
}
// nsIClassInfo overrides
NS_IMETHODIMP
nsViewSourceURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
{
*aClassIDNoAlloc = kViewSourceURICID;
return NS_OK;
}

View File

@ -40,9 +40,6 @@
#define nsViewSourceHandler_h___
#include "nsIProtocolHandler.h"
#include "nsCOMPtr.h"
#include "nsSimpleURI.h"
#include "nsINestedURI.h"
class nsViewSourceHandler : public nsIProtocolHandler
{
@ -51,50 +48,4 @@ public:
NS_DECL_NSIPROTOCOLHANDLER
};
#define NS_VIEWSOURCEURI_CID \
{ /* 2545766f-3a27-4fd1-8e88-b0886d346242 */ \
0x2545766f, \
0x3a27, \
0x4fd1, \
{ 0x8e, 0x88, 0xb0, 0x88, 0x6d, 0x34, 0x62, 0x42 } \
}
class nsViewSourceURI : public nsSimpleURI,
public nsINestedURI
{
public:
nsViewSourceURI(nsIURI* innerURI)
: nsSimpleURI(nsnull),
mInnerURI(innerURI)
{
NS_ASSERTION(innerURI, "Must have inner URI");
}
// To be used by deserialization only
nsViewSourceURI()
: nsSimpleURI(nsnull)
{
}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSINESTEDURI
// Overrides for various methods nsSimpleURI implements follow.
// nsIURI overrides
NS_IMETHOD Equals(nsIURI* other, PRBool *result);
virtual nsSimpleURI* StartClone();
// nsISerializable overrides -- we can use the same Write(), but we
// need a different Read().
NS_IMETHOD Read(nsIObjectInputStream* aStream);
// Override the nsIClassInfo method GetClassIDNoAlloc to make sure our
// nsISerializable impl works right.
NS_IMETHOD GetClassIDNoAlloc(nsCID *aClassIDNoAlloc);
protected:
nsCOMPtr<nsIURI> mInnerURI;
};
#endif /* !defined( nsViewSourceHandler_h___ ) */

View File

@ -77,6 +77,13 @@ nsAbout::NewChannel(nsIURI *aURI, nsIChannel **result)
return rv;
}
NS_IMETHODIMP
nsAbout::GetURIFlags(nsIURI *aURI, PRUint32 *result)
{
*result = 0;
return NS_OK;
}
NS_METHOD
nsAbout::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{