--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -311,17 +311,128 @@ nsScriptSecurityManager::GetSafeJSContex
return cx;
}
/* static */
PRBool
nsScriptSecurityManager::SecurityCompareURIs(nsIURI* aSourceURI,
nsIURI* aTargetURI)
{
- return NS_SecurityCompareURIs(aSourceURI, aTargetURI, sStrictFileOriginPolicy);
+ // Note that this is not an Equals() test on purpose -- for URIs that don't
+ // support host/port, we want equality to basically be object identity, for
+ // security purposes. Otherwise, for example, two javascript: URIs that
+ // are otherwise unrelated could end up "same origin", which would be
+ // unfortunate.
+ if (aSourceURI && aSourceURI == aTargetURI)
+ {
+ return PR_TRUE;
+ }
+
+ if (!aTargetURI || !aSourceURI)
+ {
+ return PR_FALSE;
+ }
+
+ // 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 PR_FALSE;
+
+ // Compare schemes
+ nsCAutoString targetScheme;
+ PRBool sameScheme = PR_FALSE;
+ if (NS_FAILED( targetBaseURI->GetScheme(targetScheme) ) ||
+ NS_FAILED( sourceBaseURI->SchemeIs(targetScheme.get(), &sameScheme) ) ||
+ !sameScheme)
+ {
+ // Not same-origin if schemes differ
+ return PR_FALSE;
+ }
+
+ // special handling for file: URIs
+ if (targetScheme.EqualsLiteral("file"))
+ {
+ // in traditional unsafe behavior all files are the same origin
+ if (!sStrictFileOriginPolicy)
+ return PR_TRUE;
+
+ nsCOMPtr<nsIFileURL> sourceFileURL(do_QueryInterface(sourceBaseURI));
+ nsCOMPtr<nsIFileURL> targetFileURL(do_QueryInterface(targetBaseURI));
+
+ if (!sourceFileURL || !targetFileURL)
+ return PR_FALSE;
+
+ nsCOMPtr<nsIFile> sourceFile, targetFile;
+
+ sourceFileURL->GetFile(getter_AddRefs(sourceFile));
+ targetFileURL->GetFile(getter_AddRefs(targetFile));
+
+ if (!sourceFile || !targetFile)
+ return PR_FALSE;
+
+ // Otherwise they had better match
+ PRBool filesAreEqual = PR_FALSE;
+ nsresult rv = sourceFile->Equals(targetFile, &filesAreEqual);
+ return NS_SUCCEEDED(rv) && filesAreEqual;
+ }
+
+ // Special handling for mailnews schemes
+ if (targetScheme.EqualsLiteral("imap") ||
+ targetScheme.EqualsLiteral("mailbox") ||
+ targetScheme.EqualsLiteral("news"))
+ {
+ // Each message is a distinct trust domain; use the
+ // whole spec for comparison
+ nsCAutoString targetSpec;
+ nsCAutoString sourceSpec;
+ return ( NS_SUCCEEDED( targetBaseURI->GetSpec(targetSpec) ) &&
+ NS_SUCCEEDED( sourceBaseURI->GetSpec(sourceSpec) ) &&
+ targetSpec.Equals(sourceSpec) );
+ }
+
+ // Compare hosts
+ nsCAutoString targetHost;
+ nsCAutoString sourceHost;
+ if (NS_FAILED( targetBaseURI->GetHost(targetHost) ) ||
+ NS_FAILED( sourceBaseURI->GetHost(sourceHost) ) ||
+ !targetHost.Equals(sourceHost, nsCaseInsensitiveCStringComparator()))
+ {
+ // Not same-origin if hosts differ
+ return PR_FALSE;
+ }
+
+ // Compare ports
+ PRInt32 targetPort;
+ nsresult rv = targetBaseURI->GetPort(&targetPort);
+ PRInt32 sourcePort;
+ if (NS_SUCCEEDED(rv))
+ rv = sourceBaseURI->GetPort(&sourcePort);
+ PRBool result = NS_SUCCEEDED(rv) && targetPort == sourcePort;
+ // If the port comparison failed, see if either URL has a
+ // port of -1. If so, replace -1 with the default port
+ // for that scheme.
+ if (NS_SUCCEEDED(rv) && !result &&
+ (sourcePort == -1 || targetPort == -1))
+ {
+ NS_ENSURE_TRUE(sIOService, PR_FALSE);
+
+ PRInt32 defaultPort = NS_GetDefaultPort(targetScheme.get());
+ if (defaultPort == -1)
+ return PR_FALSE; // No default port for this scheme
+
+ if (sourcePort == -1)
+ sourcePort = defaultPort;
+ else if (targetPort == -1)
+ targetPort = defaultPort;
+ result = targetPort == sourcePort;
+ }
+
+ return result;
}
NS_IMETHODIMP
nsScriptSecurityManager::GetChannelPrincipal(nsIChannel* aChannel,
nsIPrincipal** aPrincipal)
{
NS_PRECONDITION(aChannel, "Must have channel!");
nsCOMPtr<nsISupports> owner;
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1240,21 +1240,16 @@ public:
static void GetOfflineAppManifest(nsIDOMWindow *aWindow, nsIURI **aURI);
/**
* Check whether an application should be allowed to use offline APIs.
*/
static PRBool OfflineAppAllowed(nsIURI *aURI);
/**
- * Check whether an application should be allowed to use offline APIs.
- */
- static PRBool OfflineAppAllowed(nsIPrincipal *aPrincipal);
-
- /**
* Increases the count of blockers preventing scripts from running.
* NOTE: You might want to use nsAutoScriptBlocker rather than calling
* this directly
*/
static void AddScriptBlocker();
/**
* Decreases the count of blockers preventing scripts from running.
--- a/content/base/src/Makefile.in
+++ b/content/base/src/Makefile.in
@@ -54,17 +54,16 @@ REQUIRES = xpcom \
layout \
widget \
view \
locale \
htmlparser \
js \
webshell \
necko \
- nkcache \
mimetype \
exthandler \
chardet \
caps \
lwbrk \
uconv \
docshell \
pref \
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -68,17 +68,16 @@
#include "nsGkAtoms.h"
#include "nsIDOMWindowInternal.h"
#include "nsIPrincipal.h"
#include "nsIScriptGlobalObject.h"
#include "nsNetCID.h"
#include "nsIOfflineCacheUpdate.h"
#include "nsIApplicationCache.h"
#include "nsIApplicationCacheContainer.h"
-#include "nsIApplicationCacheService.h"
#include "nsIScriptSecurityManager.h"
#include "nsIDOMLoadStatus.h"
#include "nsICookieService.h"
#include "nsIPrompt.h"
#include "nsServiceManagerUtils.h"
#include "nsContentUtils.h"
#include "nsParserUtils.h"
#include "nsCRT.h"
@@ -92,20 +91,16 @@
#include "nsIDOMNSDocument.h"
#include "nsIRequest.h"
#include "nsNodeUtils.h"
#include "nsIDOMNode.h"
#include "nsThreadUtils.h"
#include "nsPresShellIterator.h"
#include "nsPIDOMWindow.h"
#include "mozAutoDocUpdate.h"
-#include "nsIWebNavigation.h"
-#include "nsIDocumentLoader.h"
-#include "nsICachingChannel.h"
-#include "nsICacheEntryDescriptor.h"
PRLogModuleInfo* gContentSinkLogModuleInfo;
class nsScriptLoaderObserverProxy : public nsIScriptLoaderObserver
{
public:
nsScriptLoaderObserverProxy(nsIScriptLoaderObserver* aInner)
: mInner(do_GetWeakReference(aInner))
@@ -847,314 +842,89 @@ nsContentSink::PrefetchHref(const nsAStr
mDocumentBaseURI);
if (uri) {
nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(aSource);
prefetchService->PrefetchURI(uri, mDocumentURI, domNode, aExplicit);
}
}
}
-nsresult
-nsContentSink::GetChannelCacheKey(nsIChannel* aChannel, nsACString& aCacheKey)
-{
- aCacheKey.Truncate();
-
- nsresult rv;
- nsCOMPtr<nsICachingChannel> cachingChannel = do_QueryInterface(aChannel, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsISupports> token;
- rv = cachingChannel->GetCacheToken(getter_AddRefs(token));
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsICacheEntryDescriptor> descriptor = do_QueryInterface(token, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = descriptor->GetKey(aCacheKey);
- NS_ENSURE_SUCCESS(rv, rv);
-
- return NS_OK;
-}
-
-nsresult
-nsContentSink::SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache,
- nsIURI *aManifestURI,
- PRBool aIsTopDocument,
- PRBool aFetchedWithHTTPGetOrEquiv,
- CacheSelectionAction *aAction)
-{
- *aAction = CACHE_SELECTION_NONE;
-
- nsCOMPtr<nsIApplicationCacheContainer> applicationCacheDocument =
- do_QueryInterface(mDocument);
- NS_ASSERTION(applicationCacheDocument,
- "mDocument must implement nsIApplicationCacheContainer.");
-
- nsresult rv;
-
- // We might decide on a new application cache...
- nsCOMPtr<nsIApplicationCache> applicationCache = aLoadApplicationCache;
-
- if (applicationCache) {
- nsCAutoString groupID;
- rv = applicationCache->GetGroupID(groupID);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIURI> groupURI;
- rv = NS_NewURI(getter_AddRefs(groupURI), groupID);
- NS_ENSURE_SUCCESS(rv, rv);
-
- PRBool equal = PR_FALSE;
- rv = groupURI->Equals(aManifestURI, &equal);
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (!equal) {
- // This is a foreign entry, mark it as such. If this is a
- // toplevel load, force a reload to avoid loading the foreign
- // entry. The next attempt will not choose this cache entry
- // (because it has been marked foreign).
-
- nsCAutoString cachekey;
- rv = GetChannelCacheKey(mDocument->GetChannel(), cachekey);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = applicationCache->MarkEntry(cachekey,
- nsIApplicationCache::ITEM_FOREIGN);
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (aIsTopDocument) {
- *aAction = CACHE_SELECTION_RELOAD;
- }
-
- return NS_OK;
- }
-
- if (aIsTopDocument) {
- // This is a top level document and the http manifest attribute
- // URI is equal to the manifest URI of the cache the document
- // was loaded from - associate the document with that cache and
- // invoke the cache update process.
- rv = applicationCacheDocument->SetApplicationCache(applicationCache);
- NS_ENSURE_SUCCESS(rv, rv);
-
- *aAction = CACHE_SELECTION_UPDATE;
- }
- }
- else {
- // The document was not loaded from an application cache
- // Here we know the manifest has the same origin as the
- // document. There is call to CheckMayLoad() on it above.
-
- if (!aFetchedWithHTTPGetOrEquiv) {
- // The document was not loaded using HTTP GET or equivalent
- // method. The spec says to run the cache selection algorithm w/o
- // the manifest specified but we can just do return NS_OK here.
-
- return NS_OK;
- }
-
- // If there is an existing application cache for this manifest,
- // associate it with the document.
- nsCAutoString manifestURISpec;
- rv = aManifestURI->GetAsciiSpec(manifestURISpec);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIApplicationCacheService> appCacheService =
- do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID);
- if (!appCacheService) {
- // No application cache service, nothing to do here.
- return NS_OK;
- }
-
- rv = appCacheService->GetActiveCache(manifestURISpec,
- getter_AddRefs(applicationCache));
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (applicationCache) {
- rv = applicationCacheDocument->SetApplicationCache(applicationCache);
- NS_ENSURE_SUCCESS(rv, rv);
- }
- else {
- // XXX bug 443023: if there is already a scheduled update or
- // update in progress we have to add this document as
- // an implicit entry.
- }
-
- // Always do an update in this case
- *aAction = CACHE_SELECTION_UPDATE;
- }
-
- if (applicationCache) {
- // We are now associated with an application cache. This item
- // should be marked as an implicit entry.
- nsCAutoString cachekey;
- rv = GetChannelCacheKey(mDocument->GetChannel(), cachekey);
- if (NS_SUCCEEDED(rv)) {
- rv = applicationCache->MarkEntry(cachekey,
- nsIApplicationCache::ITEM_IMPLICIT);
- NS_ENSURE_SUCCESS(rv, rv);
- }
- }
-
- return NS_OK;
-}
-
-nsresult
-nsContentSink::SelectDocAppCacheNoManifest(nsIApplicationCache *aLoadApplicationCache,
- PRBool aIsTopDocument,
- nsIURI **aManifestURI,
- CacheSelectionAction *aAction)
-{
- *aManifestURI = nsnull;
- *aAction = CACHE_SELECTION_NONE;
-
- if (!aIsTopDocument || !aLoadApplicationCache) {
- return NS_OK;
- }
-
- nsresult rv;
-
- // The document was loaded from an application cache, use that
- // application cache as the document's application cache.
- nsCOMPtr<nsIApplicationCacheContainer> applicationCacheDocument =
- do_QueryInterface(mDocument);
- NS_ASSERTION(applicationCacheDocument,
- "mDocument must implement nsIApplicationCacheContainer.");
-
- rv = applicationCacheDocument->SetApplicationCache(aLoadApplicationCache);
- NS_ENSURE_SUCCESS(rv, rv);
-
- // Return the uri and invoke the update process for the selected
- // application cache.
- nsCAutoString groupID;
- rv = aLoadApplicationCache->GetGroupID(groupID);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = NS_NewURI(aManifestURI, groupID);
- NS_ENSURE_SUCCESS(rv, rv);
-
- *aAction = CACHE_SELECTION_UPDATE;
-
- return NS_OK;
-}
-
void
nsContentSink::ProcessOfflineManifest(nsIContent *aElement)
{
- // Only check the manifest for root document nodes.
- if (aElement != mDocument->GetRootContent()) {
- return;
- }
-
- nsresult rv;
-
// Check for a manifest= attribute.
nsAutoString manifestSpec;
aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::manifest, manifestSpec);
- // Grab the application cache the document was loaded from, if any.
- nsCOMPtr<nsIApplicationCache> applicationCache;
+ if (manifestSpec.IsEmpty() ||
+ manifestSpec.FindChar('#') != kNotFound) {
+ return;
+ }
- nsCOMPtr<nsIApplicationCacheContainer> applicationCacheChannel =
- do_QueryInterface(mDocument->GetChannel());
- if (applicationCacheChannel) {
- rv = applicationCacheChannel->GetApplicationCache(
- getter_AddRefs(applicationCache));
- if (NS_FAILED(rv)) {
- return;
- }
+ // We only care about manifests in toplevel windows.
+ nsCOMPtr<nsPIDOMWindow> pwindow =
+ do_QueryInterface(mDocument->GetScriptGlobalObject());
+ if (!pwindow) {
+ return;
}
- if (manifestSpec.IsEmpty() && !applicationCache) {
- // Not loaded from an application cache, and no manifest
- // attribute. Nothing to do here.
+ nsCOMPtr<nsIDOMWindow> window =
+ do_QueryInterface(pwindow->GetOuterWindow());
+ if (!window) {
+ return;
+ }
+
+ nsCOMPtr<nsIDOMWindow> parent;
+ window->GetParent(getter_AddRefs(parent));
+ if (parent.get() != window.get()) {
+ return;
+ }
+
+ // Only update if the document has permission to use offline APIs.
+ if (!nsContentUtils::OfflineAppAllowed(mDocumentURI)) {
return;
}
- // The manifest attribute is handled differently if the document is
- // not toplevel.
- nsCOMPtr<nsIDOMWindow> window = mDocument->GetWindow();
- if (!window)
- return;
- nsCOMPtr<nsIDOMWindow> parent;
- window->GetParent(getter_AddRefs(parent));
- PRBool isTop = (parent == window);
-
- CacheSelectionAction action = CACHE_SELECTION_NONE;
- nsCOMPtr<nsIURI> manifestURI;
+ // XXX: at this point in the spec there is an algorithm for
+ // confirming whether the cache that was selected at load time was
+ // the proper application cache for this document. This will
+ // be implemented in a separate patch; For now just assume that we
+ // chose an acceptable application cache.
- if (manifestSpec.IsEmpty()) {
- rv = SelectDocAppCacheNoManifest(applicationCache,
- isTop,
- getter_AddRefs(manifestURI),
- &action);
- if (NS_FAILED(rv)) {
- return;
- }
- }
- else {
- nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(manifestURI),
- manifestSpec, mDocument,
- mDocumentURI);
- if (!manifestURI) {
- return;
- }
+ nsCOMPtr<nsIApplicationCacheContainer> channelContainer =
+ do_QueryInterface(mDocument->GetChannel());
- // Documents must list a manifest from the same origin
- rv = mDocument->NodePrincipal()->CheckMayLoad(manifestURI, PR_TRUE);
- if (NS_FAILED(rv)) {
- return;
- }
-
- // Only continue if the document has permission to use offline APIs.
- if (!nsContentUtils::OfflineAppAllowed(mDocument->NodePrincipal())) {
- return;
- }
+ nsCOMPtr<nsIApplicationCacheContainer> docContainer =
+ do_QueryInterface(mDocument);
- PRBool fetchedWithHTTPGetOrEquiv = PR_FALSE;
- nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mDocument->GetChannel()));
- if (httpChannel) {
- nsCAutoString method;
- rv = httpChannel->GetRequestMethod(method);
- if (NS_SUCCEEDED(rv))
- fetchedWithHTTPGetOrEquiv = method.Equals("GET");
- }
-
- rv = SelectDocAppCache(applicationCache, manifestURI, isTop,
- fetchedWithHTTPGetOrEquiv, &action);
- if (NS_FAILED(rv)) {
- return;
- }
+ if (channelContainer && docContainer) {
+ nsCOMPtr<nsIApplicationCache> appCache;
+ channelContainer->GetApplicationCache(getter_AddRefs(appCache));
+ docContainer->SetApplicationCache(appCache);
}
- switch (action)
- {
- case CACHE_SELECTION_NONE:
+ nsCOMPtr<nsIURI> manifestURI;
+ nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(manifestURI),
+ manifestSpec, mDocument,
+ mDocumentURI);
+ if (!manifestURI) {
return;
- case CACHE_SELECTION_UPDATE: {
- nsCOMPtr<nsIOfflineCacheUpdateService> updateService =
- do_GetService(NS_OFFLINECACHEUPDATESERVICE_CONTRACTID);
+ }
- if (updateService) {
- nsCOMPtr<nsIDOMDocument> domdoc = do_QueryInterface(mDocument);
- updateService->ScheduleOnDocumentStop(manifestURI, mDocumentURI, domdoc);
- }
- break;
+ // Documents must list a manifest from the same origin
+ nsresult rv = mDocument->NodePrincipal()->CheckMayLoad(manifestURI, PR_TRUE);
+ if (NS_FAILED(rv)) {
+ return;
}
- case CACHE_SELECTION_RELOAD: {
- // This situation occurs only for toplevel documents, see bottom
- // of SelectDocAppCache method.
- NS_ASSERTION(isTop, "Should only reload toplevel documents!");
- nsCOMPtr<nsIWebNavigation> webNav = do_QueryInterface(mDocShell);
- webNav->Stop(nsIWebNavigation::STOP_ALL);
- webNav->Reload(nsIWebNavigation::LOAD_FLAGS_NONE);
- break;
- }
- }
+ // Start the update
+ nsCOMPtr<nsIDOMDocument> domdoc = do_QueryInterface(mDocument);
+ nsCOMPtr<nsIOfflineCacheUpdateService> updateService =
+ do_GetService(NS_OFFLINECACHEUPDATESERVICE_CONTRACTID);
+ updateService->ScheduleOnDocumentStop(manifestURI, mDocumentURI, domdoc);
}
void
nsContentSink::ScrollToRef()
{
if (mRef.IsEmpty()) {
return;
}
--- a/content/base/src/nsContentSink.h
+++ b/content/base/src/nsContentSink.h
@@ -71,17 +71,16 @@ class nsIDocShell;
class nsICSSLoader;
class nsIParser;
class nsIAtom;
class nsIChannel;
class nsIContent;
class nsIViewManager;
class nsNodeInfoManager;
class nsScriptLoader;
-class nsIApplicationCache;
#ifdef NS_DEBUG
extern PRLogModuleInfo* gContentSinkLogModuleInfo;
#define SINK_TRACE_CALLS 0x1
#define SINK_TRACE_REFLOW 0x2
#define SINK_ALWAYS_REFLOW 0x4
@@ -146,35 +145,16 @@ class nsContentSink : public nsICSSLoade
virtual void EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType);
virtual void UpdateChildCounts() = 0;
protected:
nsContentSink();
virtual ~nsContentSink();
- enum CacheSelectionAction {
- // There is no offline cache manifest specified by the document,
- // or the document was loaded from a cache other than the one it
- // specifies via its manifest attribute and IS NOT a top-level
- // document, or an error occurred during the cache selection
- // algorithm.
- CACHE_SELECTION_NONE = 0,
-
- // The offline cache manifest must be updated.
- CACHE_SELECTION_UPDATE = 1,
-
- // The document was loaded from a cache other than the one it
- // specifies via its manifest attribute and IS a top-level
- // document. In this case, the document is marked as foreign in
- // the cache it was loaded from and must be reloaded from the
- // correct cache (the one it specifies).
- CACHE_SELECTION_RELOAD = 2
- };
-
nsresult Init(nsIDocument* aDoc, nsIURI* aURI,
nsISupports* aContainer, nsIChannel* aChannel);
nsresult ProcessHTTPHeaders(nsIChannel* aChannel);
nsresult ProcessHeaderData(nsIAtom* aHeader, const nsAString& aValue,
nsIContent* aContent = nsnull);
nsresult ProcessLinkHeader(nsIContent* aElement,
const nsAString& aLinkData);
@@ -186,70 +166,16 @@ protected:
const nsSubstring& aHref,
PRBool aAlternate,
const nsSubstring& aTitle,
const nsSubstring& aType,
const nsSubstring& aMedia);
void PrefetchHref(const nsAString &aHref, nsIContent *aSource,
PRBool aExplicit);
-
- // Gets the cache key (used to identify items in a cache) of the channel.
- nsresult GetChannelCacheKey(nsIChannel* aChannel, nsACString& aCacheKey);
-
- // There is an offline cache manifest attribute specified and the
- // document is allowed to use the offline cache. Process the cache
- // selection algorithm for this document and the manifest. Result is
- // an action that must be taken on the manifest, see
- // CacheSelectionAction enum above.
- //
- // @param aLoadApplicationCache
- // The application cache from which the load originated, if
- // any.
- // @param aManifestURI
- // The manifest URI listed in the document.
- // @param aIsTopDocument
- // TRUE if this is a toplevel document.
- // @param aFetchedWithHTTPGetOrEquiv
- // TRUE if this was fetched using the HTTP GET method.
- // @param aAction
- // Out parameter, returns the action that should be performed
- // by the calling function.
- nsresult SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache,
- nsIURI *aManifestURI,
- PRBool aIsTopDocument,
- PRBool aFetchedWithHTTPGetOrEquiv,
- CacheSelectionAction *aAction);
-
- // There is no offline cache manifest attribute specified. Process
- // the cache selection algorithm w/o the manifest. Result is an
- // action that must be taken, see CacheSelectionAction enum
- // above. In case the offline cache manifest has to be updated the
- // manifest URI is returned in aManifestURI.
- //
- // @param aLoadApplicationCache
- // The application cache from which the load originated, if
- // any.
- // @param aIsTopDocument
- // TRUE if this is a toplevel document.
- // @param aManifestURI
- // Out parameter, returns the manifest URI of the cache that
- // was selected.
- // @param aAction
- // Out parameter, returns the action that should be performed
- // by the calling function.
- nsresult SelectDocAppCacheNoManifest(nsIApplicationCache *aLoadApplicationCache,
- PRBool aIsTopDocument,
- nsIURI **aManifestURI,
- CacheSelectionAction *aAction);
-
- // Searches for the offline cache manifest attribute and calls one
- // of the above defined methods to select the document's application
- // cache, let it be associated with the document and eventually
- // schedule the cache update process.
void ProcessOfflineManifest(nsIContent *aElement);
// Tries to scroll to the URI's named anchor. Once we've successfully
// done that, further calls to this method will be ignored.
void ScrollToRef();
nsresult RefreshIfEnabled(nsIViewManager* vm);
// Start layout. If aIgnorePendingSheets is true, this will happen even if
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -802,26 +802,16 @@ nsContentUtils::GetOfflineAppManifest(ns
/* static */
PRBool
nsContentUtils::OfflineAppAllowed(nsIURI *aURI)
{
return NS_OfflineAppAllowed(aURI, sPrefBranch);
}
-/* static */
-PRBool
-nsContentUtils::OfflineAppAllowed(nsIPrincipal *aPrincipal)
-{
- nsCOMPtr<nsIURI> codebaseURI;
- aPrincipal->GetURI(getter_AddRefs(codebaseURI));
-
- return OfflineAppAllowed(codebaseURI);
-}
-
// static
void
nsContentUtils::Shutdown()
{
sInitialized = PR_FALSE;
NS_HTMLParanoidFragmentSinkShutdown();
NS_XHTMLParanoidFragmentSinkShutdown();
--- a/dom/src/offline/nsDOMOfflineResourceList.cpp
+++ b/dom/src/offline/nsDOMOfflineResourceList.cpp
@@ -334,21 +334,17 @@ nsDOMOfflineResourceList::Add(const nsAS
if (length > maxEntries) return NS_ERROR_NOT_AVAILABLE;
ClearCachedKeys();
nsCOMPtr<nsIOfflineCacheUpdate> update =
do_CreateInstance(NS_OFFLINECACHEUPDATE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
- nsCAutoString clientID;
- rv = appCache->GetClientID(clientID);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = update->InitPartial(mManifestURI, clientID, mDocumentURI);
+ rv = update->Init(PR_TRUE, mManifestURI, mDocumentURI);
NS_ENSURE_SUCCESS(rv, rv);
rv = update->AddDynamicURI(requestedURI);
NS_ENSURE_SUCCESS(rv, rv);
rv = update->Schedule();
NS_ENSURE_SUCCESS(rv, rv);
--- a/netwerk/base/public/nsNetUtil.h
+++ b/netwerk/base/public/nsNetUtil.h
@@ -69,17 +69,16 @@
#include "nsIStreamLoader.h"
#include "nsIUnicharStreamLoader.h"
#include "nsIPipe.h"
#include "nsIProtocolHandler.h"
#include "nsIFileProtocolHandler.h"
#include "nsIStringStream.h"
#include "nsILocalFile.h"
#include "nsIFileStreams.h"
-#include "nsIFileURL.h"
#include "nsIProtocolProxyService.h"
#include "nsIProxyInfo.h"
#include "nsIFileStreams.h"
#include "nsIBufferedStreams.h"
#include "nsIInputStreamPump.h"
#include "nsIAsyncStreamCopier.h"
#include "nsIPersistentProperties2.h"
#include "nsISyncStreamListener.h"
@@ -1461,133 +1460,9 @@ NS_OfflineAppAllowed(nsIURI *aURI, nsIPr
PRBool allowed;
rv = util->OfflineAppAllowed(aURI, aPrefBranch, &allowed);
NS_ENSURE_SUCCESS(rv, PR_FALSE);
return allowed;
}
-inline PRBool
-NS_SecurityCompareURIs(nsIURI* aSourceURI,
- nsIURI* aTargetURI,
- PRBool aStrictFileOriginPolicy)
-{
- // Note that this is not an Equals() test on purpose -- for URIs that don't
- // support host/port, we want equality to basically be object identity, for
- // security purposes. Otherwise, for example, two javascript: URIs that
- // are otherwise unrelated could end up "same origin", which would be
- // unfortunate.
- if (aSourceURI && aSourceURI == aTargetURI)
- {
- return PR_TRUE;
- }
-
- if (!aTargetURI || !aSourceURI)
- {
- return PR_FALSE;
- }
-
- // 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 PR_FALSE;
-
- // Compare schemes
- nsCAutoString targetScheme;
- PRBool sameScheme = PR_FALSE;
- if (NS_FAILED( targetBaseURI->GetScheme(targetScheme) ) ||
- NS_FAILED( sourceBaseURI->SchemeIs(targetScheme.get(), &sameScheme) ) ||
- !sameScheme)
- {
- // Not same-origin if schemes differ
- return PR_FALSE;
- }
-
- // special handling for file: URIs
- if (targetScheme.EqualsLiteral("file"))
- {
- // in traditional unsafe behavior all files are the same origin
- if (!aStrictFileOriginPolicy)
- return PR_TRUE;
-
- nsCOMPtr<nsIFileURL> sourceFileURL(do_QueryInterface(sourceBaseURI));
- nsCOMPtr<nsIFileURL> targetFileURL(do_QueryInterface(targetBaseURI));
-
- if (!sourceFileURL || !targetFileURL)
- return PR_FALSE;
-
- nsCOMPtr<nsIFile> sourceFile, targetFile;
-
- sourceFileURL->GetFile(getter_AddRefs(sourceFile));
- targetFileURL->GetFile(getter_AddRefs(targetFile));
-
- if (!sourceFile || !targetFile)
- return PR_FALSE;
-
- // Otherwise they had better match
- PRBool filesAreEqual = PR_FALSE;
- nsresult rv = sourceFile->Equals(targetFile, &filesAreEqual);
- return NS_SUCCEEDED(rv) && filesAreEqual;
- }
-
- // Special handling for mailnews schemes
- if (targetScheme.EqualsLiteral("imap") ||
- targetScheme.EqualsLiteral("mailbox") ||
- targetScheme.EqualsLiteral("news"))
- {
- // Each message is a distinct trust domain; use the
- // whole spec for comparison
- nsCAutoString targetSpec;
- nsCAutoString sourceSpec;
- return ( NS_SUCCEEDED( targetBaseURI->GetSpec(targetSpec) ) &&
- NS_SUCCEEDED( sourceBaseURI->GetSpec(sourceSpec) ) &&
- targetSpec.Equals(sourceSpec) );
- }
-
- // Compare hosts
- nsCAutoString targetHost;
- nsCAutoString sourceHost;
- if (NS_FAILED( targetBaseURI->GetAsciiHost(targetHost) ) ||
- NS_FAILED( sourceBaseURI->GetAsciiHost(sourceHost) ))
- {
- return PR_FALSE;
- }
-
-#ifdef MOZILLA_INTERNAL_API
- if (!targetHost.Equals(sourceHost, nsCaseInsensitiveCStringComparator() ))
-#else
- if (!targetHost.Equals(sourceHost, CaseInsensitiveCompare))
-#endif
- {
- return PR_FALSE;
- }
-
- // Compare ports
- PRInt32 targetPort;
- nsresult rv = targetBaseURI->GetPort(&targetPort);
- PRInt32 sourcePort;
- if (NS_SUCCEEDED(rv))
- rv = sourceBaseURI->GetPort(&sourcePort);
- PRBool result = NS_SUCCEEDED(rv) && targetPort == sourcePort;
- // If the port comparison failed, see if either URL has a
- // port of -1. If so, replace -1 with the default port
- // for that scheme.
- if (NS_SUCCEEDED(rv) && !result &&
- (sourcePort == -1 || targetPort == -1))
- {
- PRInt32 defaultPort = NS_GetDefaultPort(targetScheme.get());
- if (defaultPort == -1)
- return PR_FALSE; // No default port for this scheme
-
- if (sourcePort == -1)
- sourcePort = defaultPort;
- else if (targetPort == -1)
- targetPort = defaultPort;
- result = targetPort == sourcePort;
- }
-
- return result;
-}
-
#endif // !nsNetUtil_h__
--- a/netwerk/cache/src/nsDiskCacheDeviceSQL.cpp
+++ b/netwerk/cache/src/nsDiskCacheDeviceSQL.cpp
@@ -39,18 +39,16 @@
#include "nsCache.h"
#include "nsDiskCache.h"
#include "nsDiskCacheDeviceSQL.h"
#include "nsCacheService.h"
#include "nsNetUtil.h"
#include "nsAutoPtr.h"
#include "nsEscape.h"
-#include "nsIPrefBranch.h"
-#include "nsIPrefService.h"
#include "nsString.h"
#include "nsPrintfCString.h"
#include "nsCRT.h"
#include "nsIVariant.h"
#include "mozIStorageService.h"
#include "mozIStorageStatement.h"
#include "mozIStorageFunction.h"
@@ -689,30 +687,16 @@ nsOfflineCacheDevice::nsOfflineCacheDevi
{
}
nsOfflineCacheDevice::~nsOfflineCacheDevice()
{
Shutdown();
}
-/* static */
-PRBool
-nsOfflineCacheDevice::GetStrictFileOriginPolicy()
-{
- nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
-
- PRBool retval;
- if (prefs && NS_SUCCEEDED(prefs->GetBoolPref("security.fileuri.strict_origin_policy", &retval)))
- return retval;
-
- // As default value use true (be more strict)
- return PR_TRUE;
-}
-
PRUint32
nsOfflineCacheDevice::CacheSize()
{
AutoResetStatement statement(mStatement_CacheSize);
PRBool hasRows;
nsresult rv = statement->ExecuteStep(&hasRows);
NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && hasRows, 0);
@@ -1756,50 +1740,23 @@ nsOfflineCacheDevice::ChooseApplicationC
nsresult rv = statement->BindUTF8StringParameter(
0, key);
NS_ENSURE_SUCCESS(rv, rv);
PRBool hasRows;
rv = statement->ExecuteStep(&hasRows);
NS_ENSURE_SUCCESS(rv, rv);
- nsCOMPtr<nsIURI> keyURI;
- rv = NS_NewURI(getter_AddRefs(keyURI), key);
- NS_ENSURE_SUCCESS(rv, rv);
-
while (hasRows) {
- PRInt32 itemType;
- rv = statement->GetInt32(1, &itemType);
+ nsCString clientID;
+ rv = statement->GetUTF8String(0, clientID);
NS_ENSURE_SUCCESS(rv, rv);
- if (!(itemType & nsIApplicationCache::ITEM_FOREIGN)) {
- nsCAutoString clientID;
- rv = statement->GetUTF8String(0, clientID);
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (mActiveCaches.Contains(clientID)) {
- nsCAutoString groupID;
- rv = GetGroupForCache(clientID, groupID);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIURI> groupURI;
- rv = NS_NewURI(getter_AddRefs(groupURI), groupID);
- if (NS_SUCCEEDED(rv)) {
- // When we are choosing an initial cache to load the top
- // level document from, the URL of that document must have
- // the same origin as the manifest, according to the spec.
- // The following check is here because explicit, fallback
- // and dynamic entries might have origin different from the
- // manifest origin. XXX: dynamic shouldn't?
- if (NS_SecurityCompareURIs(keyURI, groupURI,
- GetStrictFileOriginPolicy()))
- return GetApplicationCache(clientID, out);
- }
- }
- }
+ if (mActiveCaches.Contains(clientID))
+ return GetApplicationCache(clientID, out);
rv = statement->ExecuteStep(&hasRows);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
--- a/netwerk/cache/src/nsDiskCacheDeviceSQL.h
+++ b/netwerk/cache/src/nsDiskCacheDeviceSQL.h
@@ -179,18 +179,16 @@ public:
private:
friend class nsApplicationCache;
static PLDHashOperator ShutdownApplicationCache(const nsACString &key,
nsIWeakReference *weakRef,
void *ctx);
- static PRBool GetStrictFileOriginPolicy();
-
PRBool Initialized() { return mDB != nsnull; }
nsresult InitActiveCaches();
nsresult UpdateEntry(nsCacheEntry *entry);
nsresult UpdateEntrySize(nsCacheEntry *entry, PRUint32 newSize);
nsresult DeleteEntry(nsCacheEntry *entry, PRBool deleteData);
nsresult DeleteData(nsCacheEntry *entry);
nsresult EnableEvictionObserver();
--- a/uriloader/prefetch/nsIOfflineCacheUpdate.idl
+++ b/uriloader/prefetch/nsIOfflineCacheUpdate.idl
@@ -110,17 +110,17 @@ interface nsIOfflineCacheUpdateObserver
* Each update object maintains a list of nsIDOMLoadStatus items for the
* resources it is updating. The list of these items will be available
* after the object is scheduled.
*
* One update object will be updating at a time. The active object will
* load its items one by one, sending itemCompleted() to any registered
* observers.
*/
-[scriptable, uuid(877261bb-b952-4d27-847e-859bdd47c0ec)]
+[scriptable, uuid(4b206247-82ee-46cf-a8b7-f7284e753bc2)]
interface nsIOfflineCacheUpdate : nsISupports {
/**
* Fetch the status of the running update. This will return a value
* defined in nsIDOMOfflineResourceList.
*/
readonly attribute unsigned short status;
/**
@@ -149,40 +149,31 @@ interface nsIOfflineCacheUpdate : nsISup
/**
* TRUE if the cache update completed successfully.
*/
readonly attribute boolean succeeded;
/**
* Initialize the update.
*
+ * @param aPartialUpdate
+ * TRUE if the update should just update the URIs given to it,
+ * FALSE if all URLs for the owner domain should be added.
* @param aManifestURI
- * The manifest URI to be checked.
+ * The manifest URI to be checked, or for partial updates the
+ * manifest that should own resources that are added.
* @param aDocumentURI
* The page that is requesting the update.
*/
- void init(in nsIURI aManifestURI, in nsIURI aDocumentURI);
+ void init(in boolean aPartialUpdate,
+ in nsIURI aManifestURI,
+ in nsIURI aDocumentURI);
/**
- * Initialize the update for partial processing.
- *
- * @param aManifestURI
- * The manifest URI of the related cache.
- * @param aClientID
- * Client ID of the cache to store resource to. This ClientID
- * must be ID of cache in the cache group identified by
- * the manifest URI passed in the first parameter.
- * @param aDocumentURI
- * The page that is requesting the update. May be null
- * when this information is unknown.
- */
- void initPartial(in nsIURI aManifestURI, in ACString aClientID, in nsIURI aDocumentURI);
-
- /**
- * Add a dynamic URI to the offline cache as part of the update.
+ * Add a URI to the offline cache as part of the update.
*
* @param aURI
* The URI to add.
*/
void addDynamicURI(in nsIURI aURI);
/**
* Add the update to the offline update queue. An offline-cache-update-added
--- a/uriloader/prefetch/nsOfflineCacheUpdate.cpp
+++ b/uriloader/prefetch/nsOfflineCacheUpdate.cpp
@@ -41,29 +41,27 @@
#include "nsCPrefetchService.h"
#include "nsCURILoader.h"
#include "nsIApplicationCacheContainer.h"
#include "nsIApplicationCacheService.h"
#include "nsICache.h"
#include "nsICacheService.h"
#include "nsICacheSession.h"
#include "nsICachingChannel.h"
-#include "nsIDocumentLoader.h"
#include "nsIDOMWindow.h"
#include "nsIDOMOfflineResourceList.h"
#include "nsIObserverService.h"
#include "nsIURL.h"
#include "nsIWebProgress.h"
#include "nsICryptoHash.h"
#include "nsICacheEntryDescriptor.h"
#include "nsNetCID.h"
#include "nsNetUtil.h"
#include "nsServiceManagerUtils.h"
#include "nsStreamUtils.h"
-#include "nsStringEnumerator.h"
#include "nsThreadUtils.h"
#include "prlog.h"
static nsOfflineCacheUpdateService *gOfflineCacheUpdateService = nsnull;
#if defined(PR_LOGGING)
//
// To enable logging (see prlog.h for full details):
@@ -574,17 +572,16 @@ nsOfflineManifestItem::HandleManifestLin
nsresult rv;
switch(mParserState) {
case PARSE_INIT:
case PARSE_ERROR: {
// this should have been dealt with earlier
return NS_ERROR_FAILURE;
}
-
case PARSE_CACHE_ENTRIES: {
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), line, nsnull, mURI);
if (NS_FAILED(rv))
break;
nsCAutoString scheme;
uri->GetScheme(scheme);
@@ -808,30 +805,31 @@ nsOfflineCacheUpdate::GetCacheKey(nsIURI
rv = newURI->GetAsciiSpec(aKey);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
-nsOfflineCacheUpdate::Init(nsIURI *aManifestURI,
+nsOfflineCacheUpdate::Init(PRBool aPartialUpdate,
+ nsIURI *aManifestURI,
nsIURI *aDocumentURI)
{
nsresult rv;
// Make sure the service has been initialized
nsOfflineCacheUpdateService* service =
nsOfflineCacheUpdateService::EnsureService();
if (!service)
return NS_ERROR_FAILURE;
- LOG(("nsOfflineCacheUpdate::Init [%p]", this));
+ LOG(("nsOfflineCacheUpdate::Init [%p, %d]", this, aPartialUpdate));
- mPartialUpdate = PR_FALSE;
+ mPartialUpdate = aPartialUpdate;
// Only http and https applications are supported.
PRBool match;
rv = aManifestURI->SchemeIs("http", &match);
NS_ENSURE_SUCCESS(rv, rv);
if (!match) {
rv = aManifestURI->SchemeIs("https", &match);
@@ -855,76 +853,30 @@ nsOfflineCacheUpdate::Init(nsIURI *aMani
nsCOMPtr<nsIApplicationCacheService> cacheService =
do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = cacheService->GetActiveCache(manifestSpec,
getter_AddRefs(mPreviousApplicationCache));
NS_ENSURE_SUCCESS(rv, rv);
- rv = cacheService->CreateApplicationCache(manifestSpec,
- getter_AddRefs(mApplicationCache));
- NS_ENSURE_SUCCESS(rv, rv);
+ // Partial updates to existing application caches don't need a new cache.
+ if (aPartialUpdate && mPreviousApplicationCache) {
+ mApplicationCache = mPreviousApplicationCache;
+ } else {
+ rv = cacheService->CreateApplicationCache(manifestSpec,
+ getter_AddRefs(mApplicationCache));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
rv = mApplicationCache->GetClientID(mClientID);
NS_ENSURE_SUCCESS(rv, rv);
mState = STATE_INITIALIZED;
- return NS_OK;
-}
-nsresult
-nsOfflineCacheUpdate::InitPartial(nsIURI *aManifestURI,
- const nsACString& clientID,
- nsIURI *aDocumentURI)
-{
- nsresult rv;
-
- // Make sure the service has been initialized
- nsOfflineCacheUpdateService* service =
- nsOfflineCacheUpdateService::EnsureService();
- if (!service)
- return NS_ERROR_FAILURE;
-
- LOG(("nsOfflineCacheUpdate::InitPartial [%p]", this));
-
- mPartialUpdate = PR_TRUE;
- mClientID = clientID;
- mDocumentURI = aDocumentURI;
-
- mManifestURI = aManifestURI;
- rv = mManifestURI->GetAsciiHost(mUpdateDomain);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIApplicationCacheService> cacheService =
- do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = cacheService->GetApplicationCache(mClientID,
- getter_AddRefs(mApplicationCache));
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (!mApplicationCache) {
- nsCAutoString manifestSpec;
- rv = GetCacheKey(mManifestURI, manifestSpec);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = cacheService->CreateApplicationCache
- (manifestSpec, getter_AddRefs(mApplicationCache));
- NS_ENSURE_SUCCESS(rv, rv);
- }
-
- nsCAutoString groupID;
- rv = mApplicationCache->GetGroupID(groupID);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = NS_NewURI(getter_AddRefs(mManifestURI), groupID);
- NS_ENSURE_SUCCESS(rv, rv);
-
- mState = STATE_INITIALIZED;
return NS_OK;
}
nsresult
nsOfflineCacheUpdate::HandleManifest(PRBool *aDoUpdate)
{
// Be pessimistic
*aDoUpdate = PR_FALSE;
@@ -1653,17 +1605,16 @@ nsOfflineCacheUpdateService::Schedule(ns
NS_IMETHODIMP
nsOfflineCacheUpdateService::ScheduleOnDocumentStop(nsIURI *aManifestURI,
nsIURI *aDocumentURI,
nsIDOMDocument *aDocument)
{
LOG(("nsOfflineCacheUpdateService::ScheduleOnDocumentStop [%p, manifestURI=%p, documentURI=%p doc=%p]",
this, aManifestURI, aDocumentURI, aDocument));
- // Proceed with cache update
PendingUpdate *update = new PendingUpdate();
update->mManifestURI = aManifestURI;
update->mDocumentURI = aDocumentURI;
if (!mDocUpdates.Put(aDocument, update))
return NS_ERROR_FAILURE;
return NS_OK;
}
@@ -1781,17 +1732,17 @@ nsOfflineCacheUpdateService::ScheduleUpd
}
// There is no existing update, start one.
nsRefPtr<nsOfflineCacheUpdate> update = new nsOfflineCacheUpdate();
if (!update)
return NS_ERROR_OUT_OF_MEMORY;
- rv = update->Init(aManifestURI, aDocumentURI);
+ rv = update->Init(PR_FALSE, aManifestURI, aDocumentURI);
NS_ENSURE_SUCCESS(rv, rv);
rv = update->Schedule();
NS_ENSURE_SUCCESS(rv, rv);
NS_ADDREF(*aUpdate = update);
return NS_OK;