зеркало из https://github.com/mozilla/pjs.git
Add an interface for nested URIs (like jar:, view-source:, etc) to implement
and use it in various places. Create null principals if asked for a codebase principal for a codebase that doesn't have an inherent security context (eg data: or javascript:). Bug 334407, r=biesi,dveditz, sr=darin
This commit is contained in:
Родитель
02082fc3be
Коммит
fca88cd9e1
|
@ -44,7 +44,7 @@
|
|||
#include "nsIScriptObjectPrincipal.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIJARURI.h"
|
||||
#include "nsINestedURI.h"
|
||||
#include "nspr.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
#include "nsSystemPrincipal.h"
|
||||
|
@ -266,18 +266,10 @@ nsScriptSecurityManager::SecurityCompareURIs(nsIURI* aSourceURI,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// If either uri is a jar URI, get the base URI
|
||||
nsCOMPtr<nsIJARURI> jarURI;
|
||||
nsCOMPtr<nsIURI> sourceBaseURI(aSourceURI);
|
||||
while((jarURI = do_QueryInterface(sourceBaseURI)))
|
||||
{
|
||||
jarURI->GetJARFile(getter_AddRefs(sourceBaseURI));
|
||||
}
|
||||
nsCOMPtr<nsIURI> targetBaseURI(aTargetURI);
|
||||
while((jarURI = do_QueryInterface(targetBaseURI)))
|
||||
{
|
||||
jarURI->GetJARFile(getter_AddRefs(targetBaseURI));
|
||||
}
|
||||
// If either URI is a nested URI, get the base URI
|
||||
nsCOMPtr<nsIURI> sourceBaseURI = NS_GetInnermostURI(aSourceURI);
|
||||
|
||||
nsCOMPtr<nsIURI> targetBaseURI = NS_GetInnermostURI(aTargetURI);
|
||||
|
||||
if (!sourceBaseURI || !targetBaseURI)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -1184,38 +1176,18 @@ nsScriptSecurityManager::GetBaseURIScheme(nsIURI* aURI,
|
|||
|
||||
nsresult rv;
|
||||
|
||||
// Get the innermost URI
|
||||
nsCOMPtr<nsIURI> uri = NS_GetInnermostURI(aURI);
|
||||
|
||||
//-- get the source scheme
|
||||
rv = aURI->GetScheme(aScheme);
|
||||
rv = uri->GetScheme(aScheme);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
//-- If aURI is a view-source URI, drill down to the base URI
|
||||
if (aScheme.EqualsLiteral("view-source"))
|
||||
{
|
||||
nsCAutoString path;
|
||||
rv = aURI->GetPath(path);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsCOMPtr<nsIURI> innerURI;
|
||||
rv = NS_NewURI(getter_AddRefs(innerURI), path, nsnull, nsnull,
|
||||
sIOService);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return nsScriptSecurityManager::GetBaseURIScheme(innerURI, aScheme);
|
||||
}
|
||||
|
||||
//-- If aURI is a jar URI, drill down again
|
||||
nsCOMPtr<nsIJARURI> jarURI = do_QueryInterface(aURI);
|
||||
if (jarURI)
|
||||
{
|
||||
nsCOMPtr<nsIURI> innerURI;
|
||||
jarURI->GetJARFile(getter_AddRefs(innerURI));
|
||||
if (!innerURI) return NS_ERROR_FAILURE;
|
||||
return nsScriptSecurityManager::GetBaseURIScheme(innerURI, aScheme);
|
||||
}
|
||||
|
||||
//-- if aURI is an about uri, distinguish 'safe' and 'unsafe' about URIs
|
||||
if(aScheme.EqualsLiteral("about"))
|
||||
{
|
||||
nsCAutoString path;
|
||||
rv = NS_GetAboutModuleName(aURI, path);
|
||||
rv = NS_GetAboutModuleName(uri, path);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (path.EqualsLiteral("blank") ||
|
||||
path.EqualsLiteral("mozilla") ||
|
||||
|
@ -1895,7 +1867,15 @@ NS_IMETHODIMP
|
|||
nsScriptSecurityManager::GetCodebasePrincipal(nsIURI *aURI,
|
||||
nsIPrincipal **result)
|
||||
{
|
||||
nsresult rv;
|
||||
PRBool noContext;
|
||||
nsresult rv =
|
||||
NS_URIChainHasFlags(aURI,
|
||||
nsIProtocolHandler::URI_HAS_NO_SECURITY_CONTEXT,
|
||||
&noContext);
|
||||
if (NS_FAILED(rv) || noContext) {
|
||||
return CallCreateInstance(NS_NULLPRINCIPAL_CONTRACTID, result);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
rv = CreateCodebasePrincipal(aURI, getter_AddRefs(principal));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
|
|
@ -129,7 +129,7 @@ const char XUL_FASTLOAD_FILE_BASENAME[] = "XUL";
|
|||
// Increase the subtractor when changing version, say when changing the
|
||||
// (opaque to FastLoad code) format of JS script, function, regexp, etc.
|
||||
// XDR serializations.
|
||||
#define XUL_FASTLOAD_FILE_VERSION (0xfeedbeef - 10)
|
||||
#define XUL_FASTLOAD_FILE_VERSION (0xfeedbeef - 11)
|
||||
|
||||
#define XUL_SERIALIZATION_BUFFER_SIZE (64 * 1024)
|
||||
#define XUL_DESERIALIZATION_BUFFER_SIZE (8 * 1024)
|
||||
|
|
|
@ -123,6 +123,7 @@
|
|||
#include "nsISHistoryListener.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsINestedURI.h"
|
||||
|
||||
// Editor-related
|
||||
#include "nsIEditingSession.h"
|
||||
|
@ -6812,7 +6813,8 @@ nsDocShell::DoURILoad(nsIURI * aURI,
|
|||
}
|
||||
}
|
||||
//
|
||||
// Set the owner of the channel - only for javascript and data channels.
|
||||
// Set the owner of the channel, but only for channels that can't
|
||||
// provide their own security context.
|
||||
//
|
||||
// XXX: Is seems wrong that the owner is ignored - even if one is
|
||||
// supplied) unless the URI is javascript or data.
|
||||
|
@ -6820,17 +6822,14 @@ nsDocShell::DoURILoad(nsIURI * aURI,
|
|||
// passing in. In particular, see the code and comments in LoadURI
|
||||
// where we get the current document principal as the owner if called
|
||||
// from chrome. That would be very wrong if this code changed
|
||||
// anything but javascript: and data:
|
||||
// anything but channels that can't provide their own security context!
|
||||
//
|
||||
// (Currently chrome URIs set the owner when they are created!
|
||||
// So setting a NULL owner would be bad!)
|
||||
//
|
||||
PRBool isJSOrData = PR_FALSE;
|
||||
aURI->SchemeIs("javascript", &isJSOrData);
|
||||
if (!isJSOrData) {
|
||||
aURI->SchemeIs("data", &isJSOrData);
|
||||
}
|
||||
if (isJSOrData) {
|
||||
PRBool inherit;
|
||||
rv = URIInheritsSecurityContext(aURI, &inherit);
|
||||
if (NS_SUCCEEDED(rv) && inherit) {
|
||||
channel->SetOwner(aOwner);
|
||||
}
|
||||
|
||||
|
@ -7599,7 +7598,6 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI,
|
|||
NS_IMETHODIMP
|
||||
nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, PRUint32 aLoadType)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsCOMPtr<nsIInputStream> postData;
|
||||
nsCOMPtr<nsIURI> referrerURI;
|
||||
|
@ -7614,18 +7612,15 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, PRUint32 aLoadType)
|
|||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(aEntry->GetContentType(contentType), NS_ERROR_FAILURE);
|
||||
|
||||
PRBool isJavaScript, isViewSource, isData;
|
||||
// Calling CreateAboutBlankContentViewer can set mOSHE to null, and if
|
||||
// that's the only thing holding a ref to aEntry that will cause aEntry to
|
||||
// die while we're loading it. So hold a strong ref to aEntry here, just
|
||||
// in case.
|
||||
nsCOMPtr<nsISHEntry> kungFuDeathGrip(aEntry);
|
||||
if ((NS_SUCCEEDED(uri->SchemeIs("javascript", &isJavaScript)) &&
|
||||
isJavaScript) ||
|
||||
(NS_SUCCEEDED(uri->SchemeIs("view-source", &isViewSource)) &&
|
||||
isViewSource) ||
|
||||
(NS_SUCCEEDED(uri->SchemeIs("data", &isData)) && isData)) {
|
||||
// We're loading a javascript: or data: URL from session
|
||||
PRBool inherit;
|
||||
nsresult rv = URIInheritsSecurityContext(uri, &inherit);
|
||||
if (NS_FAILED(rv) || inherit) {
|
||||
// We're loading a URL that inherits a security context from session
|
||||
// history. Replace the current document with about:blank to
|
||||
// prevent anything from the current document from leaking
|
||||
// into any JavaScript code in the URL.
|
||||
|
@ -8679,3 +8674,14 @@ nsDocShell::Observe(nsISupports *aSubject, const char *aTopic,
|
|||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
nsDocShell::URIInheritsSecurityContext(nsIURI* aURI, PRBool* aResult)
|
||||
{
|
||||
// Need to add explicit check for about:blank here too, in the
|
||||
// future. See bug 332182.
|
||||
return NS_URIChainHasFlags(aURI,
|
||||
nsIProtocolHandler::URI_HAS_NO_SECURITY_CONTEXT,
|
||||
aResult);
|
||||
}
|
||||
|
|
|
@ -462,6 +462,9 @@ protected:
|
|||
// Call BeginRestore(nsnull, PR_FALSE) for each child of this shell.
|
||||
nsresult BeginRestoreChildren();
|
||||
|
||||
// Check whether aURI should inherit our security context
|
||||
static nsresult URIInheritsSecurityContext(nsIURI* aURI, PRBool* aResult);
|
||||
|
||||
protected:
|
||||
// Override the parent setter from nsDocLoader
|
||||
virtual nsresult SetDocLoaderParent(nsDocLoader * aLoader);
|
||||
|
|
|
@ -703,19 +703,15 @@ nsWebShell::OnLinkClickSync(nsIContent *aContent,
|
|||
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aContent));
|
||||
NS_ENSURE_TRUE(node, NS_ERROR_UNEXPECTED);
|
||||
|
||||
PRBool isJS = PR_FALSE;
|
||||
PRBool isData = PR_FALSE;
|
||||
|
||||
aURI->SchemeIs("javascript", &isJS);
|
||||
aURI->SchemeIs("data", &isData);
|
||||
|
||||
if (isJS || isData) {
|
||||
PRBool inherit;
|
||||
nsresult rv = URIInheritsSecurityContext(aURI, &inherit);
|
||||
if (NS_FAILED(rv) || inherit) {
|
||||
nsCOMPtr<nsIDocument> sourceDoc = aContent->GetDocument();
|
||||
|
||||
if (!sourceDoc) {
|
||||
// The source is in a 'zombie' document, or not part of a
|
||||
// document any more. Don't let it execute any javascript in the
|
||||
// new document.
|
||||
// document any more. Don't let it perform loads in this docshell.
|
||||
// XXXbz why only for the inherit case?
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -725,8 +721,8 @@ nsWebShell::OnLinkClickSync(nsIContent *aContent,
|
|||
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
|
||||
|
||||
if (presShell->GetDocument() != sourceDoc) {
|
||||
// The source is not in the current document, don't let it
|
||||
// execute any javascript in the current document.
|
||||
// The source is not in the current document, don't let it load anything
|
||||
// that would inherit the principals of the current document.
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -765,7 +761,6 @@ nsWebShell::OnLinkClickSync(nsIContent *aContent,
|
|||
*aRequest = nsnull;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
switch(aVerb) {
|
||||
case eLinkVerb_New:
|
||||
NS_ASSERTION(target.IsEmpty(), "Losing window name information");
|
||||
|
|
|
@ -800,7 +800,7 @@ nsJSProtocolHandler::GetDefaultPort(PRInt32 *result)
|
|||
NS_IMETHODIMP
|
||||
nsJSProtocolHandler::GetProtocolFlags(PRUint32 *result)
|
||||
{
|
||||
*result = URI_NORELATIVE | URI_NOAUTH;
|
||||
*result = URI_NORELATIVE | URI_NOAUTH | URI_HAS_NO_SECURITY_CONTEXT;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,14 +47,14 @@
|
|||
*
|
||||
* The nsIURL methods operate on the <jar-entry> part of the spec.
|
||||
*/
|
||||
[scriptable, uuid(c7e410d3-85f2-11d3-9f63-006008a6efe9)]
|
||||
[scriptable, uuid(d2746619-1724-4f42-8ca8-dacaf1b269d6)]
|
||||
interface nsIJARURI : nsIURL {
|
||||
|
||||
/**
|
||||
* Returns the root URI (the one for the actual JAR file) for this JAR
|
||||
* (e.g., http://www.big.com/blue.jar).
|
||||
*/
|
||||
attribute nsIURI JARFile;
|
||||
readonly attribute nsIURI JARFile;
|
||||
|
||||
/**
|
||||
* Returns the entry specified for this JAR URI (e.g., "ocean.html"). This
|
||||
|
|
|
@ -73,6 +73,7 @@ NS_INTERFACE_MAP_BEGIN(nsJARURI)
|
|||
NS_INTERFACE_MAP_ENTRY(nsIJARURI)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISerializable)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
|
||||
NS_INTERFACE_MAP_ENTRY(nsINestedURI)
|
||||
// see nsJARURI::Equals
|
||||
if (aIID.Equals(NS_GET_IID(nsJARURI)))
|
||||
foundInterface = NS_REINTERPRET_CAST(nsISupports*, this);
|
||||
|
@ -318,6 +319,8 @@ nsJARURI::SetSpecWithBase(const nsACString &aSpec, nsIURI* aBaseURL)
|
|||
aBaseURL, getter_AddRefs(mJARFile));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
NS_TryToSetImmutable(mJARFile);
|
||||
|
||||
// skip over any extra '/' chars
|
||||
while (*delim_end == '/')
|
||||
++delim_end;
|
||||
|
@ -500,6 +503,8 @@ nsJARURI::Clone(nsIURI **result)
|
|||
rv = mJARFile->Clone(getter_AddRefs(newJARFile));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
NS_TryToSetImmutable(newJARFile);
|
||||
|
||||
nsCOMPtr<nsIURI> newJAREntryURI;
|
||||
rv = mJAREntry->Clone(getter_AddRefs(newJAREntryURI));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -759,16 +764,7 @@ nsJARURI::GetRelativeSpec(nsIURI* uriToCompare, nsACString& relativeSpec)
|
|||
NS_IMETHODIMP
|
||||
nsJARURI::GetJARFile(nsIURI* *jarFile)
|
||||
{
|
||||
*jarFile = mJARFile;
|
||||
NS_ADDREF(*jarFile);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::SetJARFile(nsIURI* jarFile)
|
||||
{
|
||||
mJARFile = jarFile;
|
||||
return NS_OK;
|
||||
return GetInnerURI(jarFile);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -790,3 +786,16 @@ nsJARURI::SetJAREntry(const nsACString &entryPath)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::GetInnerURI(nsIURI **uri)
|
||||
{
|
||||
return NS_EnsureSafeToReturn(mJARFile, uri);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARURI::GetInnermostURI(nsIURI** uri)
|
||||
{
|
||||
return NS_ImplGetInnermostURI(this, uri);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "nsIClassInfo.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsINestedURI.h"
|
||||
|
||||
#define NS_THIS_JARURI_IMPL_CID \
|
||||
{ /* 9a55f629-730b-4d08-b75b-fa7d9570a691 */ \
|
||||
|
@ -64,7 +65,10 @@
|
|||
}
|
||||
|
||||
|
||||
class nsJARURI : public nsIJARURI, nsISerializable, nsIClassInfo
|
||||
class nsJARURI : public nsIJARURI,
|
||||
public nsISerializable,
|
||||
public nsIClassInfo,
|
||||
public nsINestedURI
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -73,6 +77,7 @@ public:
|
|||
NS_DECL_NSIJARURI
|
||||
NS_DECL_NSISERIALIZABLE
|
||||
NS_DECL_NSICLASSINFO
|
||||
NS_DECL_NSINESTEDURI
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_THIS_JARURI_IMPL_CID)
|
||||
|
||||
|
|
|
@ -102,6 +102,7 @@ XPIDLSRCS = \
|
|||
nsISyncStreamListener.idl \
|
||||
nsIUnicharStreamLoader.idl \
|
||||
nsIStandardURL.idl \
|
||||
nsINestedURI.idl \
|
||||
nsIURLParser.idl \
|
||||
nsIURIChecker.idl \
|
||||
nsISecurityEventSink.idl \
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/* -*- Mode: C++; tab-width: 2; 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
|
||||
* 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 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 "nsISupports.idl"
|
||||
|
||||
interface nsIURI;
|
||||
|
||||
/**
|
||||
* nsINestedURI is an interface that must be implemented by any nsIURI
|
||||
* implementation which has an "inner" URI that it actually gets data
|
||||
* from.
|
||||
*/
|
||||
[scriptable, uuid(6de2c874-796c-46bf-b57f-0d7bd7d6cab0)]
|
||||
interface nsINestedURI : nsISupports
|
||||
{
|
||||
/**
|
||||
* The inner URI for this nested URI. This must not return null if the
|
||||
* getter succeeds; URIs that have no inner must not QI to this interface.
|
||||
* Dynamically changing whether there is an inner URI is not allowed.
|
||||
*
|
||||
* Modifying the returned URI must not in any way modify the nested URI; this
|
||||
* means the returned URI must be either immutable or a clone.
|
||||
*/
|
||||
readonly attribute nsIURI innerURI;
|
||||
|
||||
/**
|
||||
* The innermost URI for this nested URI. This must not return null if the
|
||||
* getter succeeds. This is equivalent to repeatedly calling innerURI while
|
||||
* the returned URI QIs to nsINestedURI.
|
||||
*
|
||||
* Modifying the returned URI must not in any way modify the nested URI; this
|
||||
* means the returned URI must be either immutable or a clone.
|
||||
*/
|
||||
readonly attribute nsIURI innermostURI;
|
||||
};
|
|
@ -39,10 +39,12 @@
|
|||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIURI;
|
||||
|
||||
/**
|
||||
* nsINetUtil provides various network-related utility methods.
|
||||
*/
|
||||
[scriptable, uuid(e379f39e-80bd-4ac5-a35a-27e7739f837d)]
|
||||
[scriptable, uuid(4a1f4ab4-d527-4606-b0f7-53a27f20804c)]
|
||||
interface nsINetUtil : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -77,4 +79,28 @@ interface nsINetUtil : nsISupports
|
|||
* escape a string with %00-style escaping
|
||||
*/
|
||||
ACString escapeString(in ACString aString, in unsigned long aEscapeType);
|
||||
|
||||
/**
|
||||
* Test whether the given URI's handler has the given protocol flags.
|
||||
*
|
||||
* @param aURI the URI in question
|
||||
* @param aFlags the flags we're testing for.
|
||||
*
|
||||
* @return whether the protocol handler for aURI has all the flags
|
||||
* in aFlags.
|
||||
*/
|
||||
boolean protocolHasFlags(in nsIURI aURI, in unsigned long aFlag);
|
||||
|
||||
/**
|
||||
* Test whether the protocol handler for this URI or that for any of
|
||||
* its inner URIs has the given protocol flags. This will QI aURI to
|
||||
* nsINestedURI and walk the nested URI chain.
|
||||
*
|
||||
* @param aURI the URI in question
|
||||
* @param aFlags the flags we're testing for.
|
||||
*
|
||||
* @return whether any of the protocol handlers involved have all the flags
|
||||
* in aFlags.
|
||||
*/
|
||||
boolean URIChainHasFlags(in nsIURI aURI, in unsigned long aFlags);
|
||||
};
|
||||
|
|
|
@ -134,6 +134,13 @@ interface nsIProtocolHandler : nsISupports
|
|||
*/
|
||||
const unsigned long URI_NOAUTH = (1<<1);
|
||||
|
||||
/**
|
||||
* The URIs for this protocol have no inherent security context. That is,
|
||||
* it's not possible to decide what a document loaded from one of these
|
||||
* URIs should be allowed to do.
|
||||
*/
|
||||
const unsigned long URI_HAS_NO_SECURITY_CONTEXT = (1<<4);
|
||||
|
||||
/**
|
||||
* This protocol handler can be proxied via a proxy (socks or http)
|
||||
* (e.g., irc, smtp, http, etc.). If the protocol supports transparent
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIMutable.idl"
|
||||
|
||||
interface nsIURI;
|
||||
|
||||
|
@ -49,8 +49,8 @@ interface nsIURI;
|
|||
*
|
||||
* @status UNDER_REVIEW
|
||||
*/
|
||||
[scriptable, uuid(8793370a-311f-11d4-9876-00c04fa0cf4a)]
|
||||
interface nsIStandardURL : nsISupports
|
||||
[scriptable, uuid(babd6cca-ebe7-4329-967c-d6b9e33caa81)]
|
||||
interface nsIStandardURL : nsIMutable
|
||||
{
|
||||
/**
|
||||
* blah:foo/bar => blah://foo/bar
|
||||
|
@ -101,11 +101,4 @@ interface nsIStandardURL : nsISupports
|
|||
in AUTF8String aSpec,
|
||||
in string aOriginCharset,
|
||||
in nsIURI aBaseURI);
|
||||
|
||||
/**
|
||||
* Control whether or not this URL can be modified. Protocol handlers
|
||||
* can set this flag before handing out an URL to ensure that it is not
|
||||
* inadvertently modified.
|
||||
*/
|
||||
attribute boolean mutable;
|
||||
};
|
||||
|
|
|
@ -88,6 +88,8 @@
|
|||
#include "nsINetUtil.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsINestedURI.h"
|
||||
#include "nsIMutable.h"
|
||||
|
||||
// Helper, to simplify getting the I/O service.
|
||||
inline const nsGetServiceByContractIDWithError
|
||||
|
@ -1041,4 +1043,116 @@ NS_IsOffline()
|
|||
return offline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper functions for implementing nsINestedURI::innermostURI.
|
||||
*
|
||||
* Note that NS_DoImplGetInnermostURI is "private" -- call
|
||||
* NS_ImplGetInnermostURI instead.
|
||||
*/
|
||||
inline nsresult
|
||||
NS_DoImplGetInnermostURI(nsINestedURI* nestedURI, nsIURI** result)
|
||||
{
|
||||
NS_PRECONDITION(nestedURI, "Must have a nested URI!");
|
||||
NS_PRECONDITION(!*result, "Must have null *result");
|
||||
|
||||
nsCOMPtr<nsIURI> inner;
|
||||
nsresult rv = nestedURI->GetInnerURI(getter_AddRefs(inner));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsINestedURI> nestedInner(do_QueryInterface(inner));
|
||||
if (!nestedInner) {
|
||||
// Found the innermost one
|
||||
inner.swap(*result);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_DoImplGetInnermostURI(nestedInner, result);
|
||||
}
|
||||
|
||||
inline nsresult
|
||||
NS_ImplGetInnermostURI(nsINestedURI* nestedURI, nsIURI** result)
|
||||
{
|
||||
// Make it safe to use swap()
|
||||
*result = nsnull;
|
||||
|
||||
return NS_DoImplGetInnermostURI(nestedURI, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that ensures that |result| is a URI that's safe to
|
||||
* return. If |uri| is immutable, just returns it, otherwise returns
|
||||
* a clone. |uri| must not be null.
|
||||
*/
|
||||
inline nsresult
|
||||
NS_EnsureSafeToReturn(nsIURI* uri, nsIURI** result)
|
||||
{
|
||||
NS_PRECONDITION(uri, "Must have a URI");
|
||||
|
||||
// Assume mutable until told otherwise
|
||||
PRBool isMutable = PR_TRUE;
|
||||
nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(uri));
|
||||
if (mutableObj) {
|
||||
nsresult rv = mutableObj->GetMutable(&isMutable);
|
||||
isMutable = NS_FAILED(rv) || isMutable;
|
||||
}
|
||||
|
||||
if (!isMutable) {
|
||||
NS_ADDREF(*result = uri);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return uri->Clone(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that tries to set the argument URI to be immutable
|
||||
*/
|
||||
inline void
|
||||
NS_TryToSetImmutable(nsIURI* uri)
|
||||
{
|
||||
nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(uri));
|
||||
if (mutableObj) {
|
||||
mutableObj->SetMutable(PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for testing whether the given URI, or any of its
|
||||
* inner URIs, has all the given protocol flags.
|
||||
*/
|
||||
inline nsresult
|
||||
NS_URIChainHasFlags(nsIURI *uri,
|
||||
PRUint32 flags,
|
||||
PRBool *result)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsINetUtil> util = do_GetIOService(&rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return util->URIChainHasFlags(uri, flags, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for getting the innermost URI for a given URI. The return
|
||||
* value could be just the object passed in if it's not a nested URI.
|
||||
*/
|
||||
inline already_AddRefed<nsIURI>
|
||||
NS_GetInnermostURI(nsIURI *uri)
|
||||
{
|
||||
NS_PRECONDITION(uri, "Must have URI");
|
||||
|
||||
nsCOMPtr<nsINestedURI> nestedURI(do_QueryInterface(uri));
|
||||
if (!nestedURI) {
|
||||
NS_ADDREF(uri);
|
||||
return uri;
|
||||
}
|
||||
|
||||
nsresult rv = nestedURI->GetInnermostURI(&uri);
|
||||
if (NS_FAILED(rv)) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return uri;
|
||||
}
|
||||
|
||||
#endif // !nsNetUtil_h__
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* vim:set ts=4 sw=4 cindent et: */
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:set ts=4 sw=4 cindent et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -67,6 +67,7 @@
|
|||
#include "nsIRecyclingAllocator.h"
|
||||
#include "nsISocketTransport.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsINestedURI.h"
|
||||
|
||||
#define PORT_PREF_PREFIX "network.security.ports."
|
||||
#define PORT_PREF(x) PORT_PREF_PREFIX x
|
||||
|
@ -795,6 +796,60 @@ nsIOService::ParseContentType(const nsACString &aTypeHeader,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::ProtocolHasFlags(nsIURI *uri,
|
||||
PRUint32 flags,
|
||||
PRBool *result)
|
||||
{
|
||||
NS_ENSURE_ARG(uri);
|
||||
|
||||
*result = PR_FALSE;
|
||||
nsCAutoString scheme;
|
||||
nsresult rv = uri->GetScheme(scheme);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 protocolFlags;
|
||||
rv = GetProtocolFlags(scheme.get(), &protocolFlags);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*result = (protocolFlags & flags) == flags;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::URIChainHasFlags(nsIURI *uri,
|
||||
PRUint32 flags,
|
||||
PRBool *result)
|
||||
{
|
||||
nsresult rv = ProtocolHasFlags(uri, flags, result);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (*result) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Dig deeper into the chain. Note that this is not a do/while loop to
|
||||
// avoid the extra addref/release on |uri| in the common (non-nested) case.
|
||||
nsCOMPtr<nsINestedURI> nestedURI = do_QueryInterface(uri);
|
||||
while (nestedURI) {
|
||||
nsCOMPtr<nsIURI> innerURI;
|
||||
rv = nestedURI->GetInnerURI(getter_AddRefs(innerURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ProtocolHasFlags(innerURI, flags, result);
|
||||
|
||||
if (*result) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nestedURI = do_QueryInterface(innerURI);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::SetManageOfflineStatus(PRBool aManage) {
|
||||
PRBool wasManaged = mManageOfflineStatus;
|
||||
|
|
|
@ -61,6 +61,7 @@ static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
|
|||
// nsSimpleURI methods:
|
||||
|
||||
nsSimpleURI::nsSimpleURI(nsISupports* outer)
|
||||
: mMutable(PR_TRUE)
|
||||
{
|
||||
NS_INIT_AGGREGATED(outer);
|
||||
}
|
||||
|
@ -85,6 +86,8 @@ nsSimpleURI::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr)
|
|||
*aInstancePtr = NS_STATIC_CAST(nsISerializable*, this);
|
||||
} else if (aIID.Equals(NS_GET_IID(nsIClassInfo))) {
|
||||
*aInstancePtr = NS_STATIC_CAST(nsIClassInfo*, this);
|
||||
} else if (aIID.Equals(NS_GET_IID(nsIMutable))) {
|
||||
*aInstancePtr = NS_STATIC_CAST(nsIMutable*, this);
|
||||
} else {
|
||||
*aInstancePtr = nsnull;
|
||||
return NS_NOINTERFACE;
|
||||
|
@ -101,6 +104,9 @@ nsSimpleURI::Read(nsIObjectInputStream* aStream)
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
rv = aStream->ReadBoolean(&mMutable);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = aStream->ReadCString(mScheme);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
@ -115,6 +121,9 @@ nsSimpleURI::Write(nsIObjectOutputStream* aStream)
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
rv = aStream->WriteBoolean(mMutable);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = aStream->WriteStringZ(mScheme.get());
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
@ -137,6 +146,8 @@ nsSimpleURI::GetSpec(nsACString &result)
|
|||
NS_IMETHODIMP
|
||||
nsSimpleURI::SetSpec(const nsACString &aSpec)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
const nsAFlatCString& flat = PromiseFlatCString(aSpec);
|
||||
const char* specPtr = flat.get();
|
||||
|
||||
|
@ -181,6 +192,8 @@ nsSimpleURI::GetScheme(nsACString &result)
|
|||
NS_IMETHODIMP
|
||||
nsSimpleURI::SetScheme(const nsACString &scheme)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
mScheme = scheme;
|
||||
ToLowerCase(mScheme);
|
||||
return NS_OK;
|
||||
|
@ -202,6 +215,8 @@ nsSimpleURI::GetUserPass(nsACString &result)
|
|||
NS_IMETHODIMP
|
||||
nsSimpleURI::SetUserPass(const nsACString &userPass)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -214,6 +229,8 @@ nsSimpleURI::GetUsername(nsACString &result)
|
|||
NS_IMETHODIMP
|
||||
nsSimpleURI::SetUsername(const nsACString &userName)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -226,6 +243,8 @@ nsSimpleURI::GetPassword(nsACString &result)
|
|||
NS_IMETHODIMP
|
||||
nsSimpleURI::SetPassword(const nsACString &password)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -240,6 +259,8 @@ nsSimpleURI::GetHostPort(nsACString &result)
|
|||
NS_IMETHODIMP
|
||||
nsSimpleURI::SetHostPort(const nsACString &result)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -254,6 +275,8 @@ nsSimpleURI::GetHost(nsACString &result)
|
|||
NS_IMETHODIMP
|
||||
nsSimpleURI::SetHost(const nsACString &host)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -268,6 +291,8 @@ nsSimpleURI::GetPort(PRInt32 *result)
|
|||
NS_IMETHODIMP
|
||||
nsSimpleURI::SetPort(PRInt32 port)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -281,6 +306,8 @@ nsSimpleURI::GetPath(nsACString &result)
|
|||
NS_IMETHODIMP
|
||||
nsSimpleURI::SetPath(const nsACString &path)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
mPath = path;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -322,13 +349,21 @@ nsSimpleURI::SchemeIs(const char *i_Scheme, PRBool *o_Equals)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/* virtual */ nsSimpleURI*
|
||||
nsSimpleURI::StartClone()
|
||||
{
|
||||
return new nsSimpleURI(nsnull); // XXX outer?
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::Clone(nsIURI* *result)
|
||||
{
|
||||
nsSimpleURI* url = new nsSimpleURI(nsnull); // XXX outer?
|
||||
nsSimpleURI* url = StartClone();
|
||||
if (url == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Note: |url| may well have mMutable false at this point, so
|
||||
// don't call any setter methods.
|
||||
url->mScheme = mScheme;
|
||||
url->mPath = mPath;
|
||||
|
||||
|
@ -390,6 +425,8 @@ nsSimpleURI::GetHelperForLanguage(PRUint32 language, nsISupports **_retval)
|
|||
NS_IMETHODIMP
|
||||
nsSimpleURI::GetContractID(char * *aContractID)
|
||||
{
|
||||
// Make sure to modify any subclasses as needed if this ever
|
||||
// changes.
|
||||
*aContractID = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -404,6 +441,8 @@ nsSimpleURI::GetClassDescription(char * *aClassDescription)
|
|||
NS_IMETHODIMP
|
||||
nsSimpleURI::GetClassID(nsCID * *aClassID)
|
||||
{
|
||||
// Make sure to modify any subclasses as needed if this ever
|
||||
// changes to not call the virtual GetClassIDNoAlloc.
|
||||
*aClassID = (nsCID*) nsMemory::Alloc(sizeof(nsCID));
|
||||
if (!*aClassID)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -430,3 +469,23 @@ nsSimpleURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
|
|||
*aClassIDNoAlloc = kSimpleURICID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// nsSimpleURI::nsISimpleURI
|
||||
//----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::GetMutable(PRBool *value)
|
||||
{
|
||||
*value = mMutable;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::SetMutable(PRBool value)
|
||||
{
|
||||
NS_ENSURE_ARG(mMutable || !value);
|
||||
|
||||
mMutable = value;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "nsISerializable.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIClassInfo.h"
|
||||
#include "nsIMutable.h"
|
||||
|
||||
#define NS_THIS_SIMPLEURI_IMPLEMENTATION_CID \
|
||||
{ /* 22b8f64a-2f7b-11d3-8cd0-0060b0fc14a3 */ \
|
||||
|
@ -52,13 +53,17 @@
|
|||
{0x8c, 0xd0, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
|
||||
}
|
||||
|
||||
class nsSimpleURI : public nsIURI, public nsISerializable, public nsIClassInfo
|
||||
class nsSimpleURI : public nsIURI,
|
||||
public nsISerializable,
|
||||
public nsIClassInfo,
|
||||
public nsIMutable
|
||||
{
|
||||
public:
|
||||
NS_DECL_AGGREGATED
|
||||
NS_DECL_NSIURI
|
||||
NS_DECL_NSISERIALIZABLE
|
||||
NS_DECL_NSICLASSINFO
|
||||
NS_DECL_NSIMUTABLE
|
||||
|
||||
// nsSimpleURI methods:
|
||||
|
||||
|
@ -66,8 +71,11 @@ public:
|
|||
virtual ~nsSimpleURI();
|
||||
|
||||
protected:
|
||||
virtual nsSimpleURI* StartClone();
|
||||
|
||||
nsCString mScheme;
|
||||
nsCString mPath;
|
||||
PRBool mMutable;
|
||||
};
|
||||
|
||||
#endif // nsSimpleURI_h__
|
||||
|
|
|
@ -934,6 +934,7 @@ NS_INTERFACE_MAP_BEGIN(nsStandardURL)
|
|||
NS_INTERFACE_MAP_ENTRY(nsIStandardURL)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISerializable)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIMutable)
|
||||
// see nsStandardURL::Equals
|
||||
if (aIID.Equals(kThisImplCID))
|
||||
foundInterface = NS_STATIC_CAST(nsIURI *, this);
|
||||
|
@ -2600,6 +2601,8 @@ nsStandardURL::GetMutable(PRBool *value)
|
|||
NS_IMETHODIMP
|
||||
nsStandardURL::SetMutable(PRBool value)
|
||||
{
|
||||
NS_ENSURE_ARG(mMutable || !value);
|
||||
|
||||
mMutable = value;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2683,6 +2686,12 @@ nsStandardURL::Read(nsIObjectInputStream *stream)
|
|||
rv = NS_ReadOptionalCString(stream, mOriginCharset);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRBool isMutable;
|
||||
rv = stream->ReadBoolean(&isMutable);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
mMutable = isMutable;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2745,6 +2754,9 @@ nsStandardURL::Write(nsIObjectOutputStream *stream)
|
|||
rv = NS_WriteOptionalStringZ(stream, mOriginCharset.get());
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = stream->WriteBoolean(mMutable);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ public:
|
|||
NS_DECL_NSISTANDARDURL
|
||||
NS_DECL_NSISERIALIZABLE
|
||||
NS_DECL_NSICLASSINFO
|
||||
NS_DECL_NSIMUTABLE
|
||||
|
||||
nsStandardURL(PRBool aSupportsFileURL = PR_FALSE);
|
||||
virtual ~nsStandardURL();
|
||||
|
|
|
@ -226,6 +226,7 @@ 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
|
||||
|
@ -1133,6 +1134,11 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
|
|||
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "view-source",
|
||||
nsViewSourceHandlerConstructor
|
||||
},
|
||||
{ "The ViewSource URI",
|
||||
NS_VIEWSOURCEURI_CID,
|
||||
nsnull,
|
||||
nsViewSourceURIConstructor
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
|
|
@ -89,7 +89,7 @@ nsDataHandler::GetDefaultPort(PRInt32 *result) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsDataHandler::GetProtocolFlags(PRUint32 *result) {
|
||||
*result = URI_NORELATIVE | URI_NOAUTH;
|
||||
*result = URI_NORELATIVE | URI_NOAUTH | URI_HAS_NO_SECURITY_CONTEXT;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,8 @@ CPPSRCS = \
|
|||
nsViewSourceChannel.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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:set ts=4 sw=4 sts=4 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
@ -41,6 +41,11 @@
|
|||
#include "nsViewSourceHandler.h"
|
||||
#include "nsViewSourceChannel.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIObjectInputStream.h"
|
||||
#include "nsIObjectOutputStream.h"
|
||||
#include "nsIProgrammingLanguage.h"
|
||||
|
||||
#define VIEW_SOURCE "view-source"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -52,7 +57,7 @@ NS_IMPL_ISUPPORTS1(nsViewSourceHandler, nsIProtocolHandler)
|
|||
NS_IMETHODIMP
|
||||
nsViewSourceHandler::GetScheme(nsACString &result)
|
||||
{
|
||||
result.AssignLiteral("view-source");
|
||||
result.AssignLiteral(VIEW_SOURCE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -76,7 +81,7 @@ nsViewSourceHandler::NewURI(const nsACString &aSpec,
|
|||
nsIURI *aBaseURI,
|
||||
nsIURI **aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
*aResult = nsnull;
|
||||
|
||||
// Extract inner URL and normalize to ASCII. This is done to properly
|
||||
// support IDN in cases like "view-source:http://www.szalagavató.hu/"
|
||||
|
@ -86,10 +91,13 @@ nsViewSourceHandler::NewURI(const nsACString &aSpec,
|
|||
return NS_ERROR_MALFORMED_URI;
|
||||
|
||||
nsCOMPtr<nsIURI> innerURI;
|
||||
rv = NS_NewURI(getter_AddRefs(innerURI), Substring(aSpec, colon + 1), aCharset);
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(innerURI),
|
||||
Substring(aSpec, colon + 1), aCharset);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
NS_TryToSetImmutable(innerURI);
|
||||
|
||||
nsCAutoString asciiSpec;
|
||||
rv = innerURI->GetAsciiSpec(asciiSpec);
|
||||
if (NS_FAILED(rv))
|
||||
|
@ -97,18 +105,23 @@ nsViewSourceHandler::NewURI(const nsACString &aSpec,
|
|||
|
||||
// put back our scheme and construct a simple-uri wrapper
|
||||
|
||||
asciiSpec.Insert("view-source:", 0);
|
||||
asciiSpec.Insert(VIEW_SOURCE ":", 0);
|
||||
|
||||
nsIURI *uri;
|
||||
rv = CallCreateInstance(NS_SIMPLEURI_CONTRACTID, nsnull, &uri);
|
||||
// We can't swap() from an nsRefPtr<nsViewSourceURI> to an nsIURI**, sadly.
|
||||
nsViewSourceURI* ourURI = new nsViewSourceURI(innerURI);
|
||||
nsCOMPtr<nsIURI> uri = ourURI;
|
||||
if (!uri)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = ourURI->SetSpec(asciiSpec);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = uri->SetSpec(asciiSpec);
|
||||
if (NS_FAILED(rv))
|
||||
NS_RELEASE(uri);
|
||||
else
|
||||
*aResult = uri;
|
||||
// Make the URI immutable so it's impossible to get it out of sync
|
||||
// with mInnerURI.
|
||||
ourURI->SetMutable(PR_FALSE);
|
||||
|
||||
uri.swap(*aResult);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -138,3 +151,98 @@ 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;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,9 @@
|
|||
#define nsViewSourceHandler_h___
|
||||
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsSimpleURI.h"
|
||||
#include "nsINestedURI.h"
|
||||
|
||||
class nsViewSourceHandler : public nsIProtocolHandler
|
||||
{
|
||||
|
@ -48,4 +51,50 @@ 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___ ) */
|
||||
|
|
|
@ -360,7 +360,7 @@ PRBool nsExternalProtocolHandler::HaveProtocolHandler(nsIURI * aURI)
|
|||
NS_IMETHODIMP nsExternalProtocolHandler::GetProtocolFlags(PRUint32 *aUritype)
|
||||
{
|
||||
// Make it norelative since it is a simple uri
|
||||
*aUritype = URI_NORELATIVE;
|
||||
*aUritype = URI_NORELATIVE | URI_NOAUTH | URI_HAS_NO_SECURITY_CONTEXT;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -124,6 +124,7 @@ XPIDLSRCS = \
|
|||
nsIExceptionService.idl \
|
||||
nsIVersionComparator.idl \
|
||||
nsIUUIDGenerator.idl \
|
||||
nsIMutable.idl \
|
||||
$(NULL)
|
||||
|
||||
ifdef GC_LEAK_DETECTOR
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/* -*- Mode: C++; tab-width: 2; 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
|
||||
* 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 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 "nsISupports.idl"
|
||||
|
||||
/**
|
||||
* nsIMutable defines an interface to be implemented by objects which
|
||||
* can be made immutable.
|
||||
*/
|
||||
[scriptable, uuid(321578d0-03c1-4d95-8821-021ac612d18d)]
|
||||
interface nsIMutable : nsISupports
|
||||
{
|
||||
/**
|
||||
* Control whether or not this object can be modified. If the flag is
|
||||
* false, no modification is allowed. Once the flag has been set to false,
|
||||
* it cannot be reset back to true -- attempts to do so throw
|
||||
* NS_ERROR_INVALID_ARG.
|
||||
*/
|
||||
attribute boolean mutable;
|
||||
};
|
Загрузка…
Ссылка в новой задаче