зеркало из https://github.com/mozilla/pjs.git
Save the principal in the session history entry so that reloading a data: URL
will do the right thing. Also, change CheckLoadURI to allow null principals to load things that anyone can load (e.g. http:// URIs). Bug 337260, r=dveditz, sr=jst
This commit is contained in:
Родитель
64681af28a
Коммит
66d9ce92e5
|
@ -1254,14 +1254,6 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
|
|||
nsresult rv = GetBaseURIScheme(sourceURI, sourceScheme);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
NS_NAMED_LITERAL_STRING(errorTag, "CheckLoadURIError");
|
||||
|
||||
// Don't allow null principals to load anything
|
||||
if (sourceScheme.LowerCaseEqualsLiteral(NS_NULLPRINCIPAL_SCHEME)) {
|
||||
ReportError(nsnull, errorTag, sourceURI, aTargetURI);
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
// Some loads are not allowed from mail/news messages
|
||||
if ((aFlags & nsIScriptSecurityManager::DISALLOW_FROM_MAIL) &&
|
||||
(sourceScheme.LowerCaseEqualsLiteral("mailbox") ||
|
||||
|
@ -1287,9 +1279,11 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
|
|||
}
|
||||
|
||||
if (targetScheme.Equals(sourceScheme,
|
||||
nsCaseInsensitiveCStringComparator()))
|
||||
nsCaseInsensitiveCStringComparator()) &&
|
||||
!sourceScheme.LowerCaseEqualsLiteral(NS_NULLPRINCIPAL_SCHEME))
|
||||
{
|
||||
// every scheme can access another URI from the same scheme
|
||||
// every scheme can access another URI from the same scheme,
|
||||
// as long as they don't represent null principals.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1334,6 +1328,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
|
|||
{ NS_NULLPRINCIPAL_SCHEME, DenyProtocol }
|
||||
};
|
||||
|
||||
NS_NAMED_LITERAL_STRING(errorTag, "CheckLoadURIError");
|
||||
for (unsigned i=0; i < sizeof(protocolList)/sizeof(protocolList[0]); i++)
|
||||
{
|
||||
if (targetScheme.LowerCaseEqualsASCII(protocolList[i].name))
|
||||
|
|
|
@ -7582,6 +7582,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI,
|
|||
nsCOMPtr<nsIURI> referrerURI;
|
||||
nsCOMPtr<nsISupports> cacheKey;
|
||||
nsCOMPtr<nsISupports> cacheToken;
|
||||
nsCOMPtr<nsISupports> owner;
|
||||
PRBool expired = PR_FALSE;
|
||||
PRBool discardLayoutState = PR_FALSE;
|
||||
if (aChannel) {
|
||||
|
@ -7609,6 +7610,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI,
|
|||
|
||||
discardLayoutState = ShouldDiscardLayoutState(httpChannel);
|
||||
}
|
||||
aChannel->GetOwner(getter_AddRefs(owner));
|
||||
}
|
||||
|
||||
//Title is set in nsDocShell::SetTitle()
|
||||
|
@ -7617,7 +7619,8 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI,
|
|||
inputStream, // Post data stream
|
||||
nsnull, // LayoutHistory state
|
||||
cacheKey, // CacheKey
|
||||
mContentTypeHint); // Content-type
|
||||
mContentTypeHint, // Content-type
|
||||
owner); // Channel owner
|
||||
entry->SetReferrerURI(referrerURI);
|
||||
/* If cache got a 'no-store', ask SH not to store
|
||||
* HistoryLayoutState. By default, SH will set this
|
||||
|
@ -7694,6 +7697,7 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, PRUint32 aLoadType)
|
|||
nsCOMPtr<nsIInputStream> postData;
|
||||
nsCOMPtr<nsIURI> referrerURI;
|
||||
nsCAutoString contentType;
|
||||
nsCOMPtr<nsISupports> owner;
|
||||
|
||||
NS_ENSURE_TRUE(aEntry, NS_ERROR_FAILURE);
|
||||
|
||||
|
@ -7703,19 +7707,21 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, PRUint32 aLoadType)
|
|||
NS_ENSURE_SUCCESS(aEntry->GetPostData(getter_AddRefs(postData)),
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(aEntry->GetContentType(contentType), NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(aEntry->GetOwner(getter_AddRefs(owner)),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
// 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);
|
||||
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.
|
||||
PRBool isJS;
|
||||
nsresult rv = uri->SchemeIs("javascript", &isJS);
|
||||
if (NS_FAILED(rv) || isJS) {
|
||||
// We're loading a URL that will execute script from inside asyncOpen.
|
||||
// Replace the current document with about:blank now to prevent
|
||||
// anything from the current document from leaking into any JavaScript
|
||||
// code in the URL.
|
||||
rv = CreateAboutBlankContentViewer();
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -7724,6 +7730,14 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, PRUint32 aLoadType)
|
|||
// user prevented it). Interrupt the history load.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!owner) {
|
||||
// Ensure that we have an owner. Otherwise javascript: URIs will
|
||||
// pick it up from the about:blank page we just loaded, and we
|
||||
// don't really want even that in this case.
|
||||
owner = do_CreateInstance("@mozilla.org/nullprincipal;1");
|
||||
NS_ENSURE_TRUE(owner, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is a valid postdata *and* the user pressed
|
||||
|
@ -7756,7 +7770,7 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, PRUint32 aLoadType)
|
|||
|
||||
rv = InternalLoad(uri,
|
||||
referrerURI,
|
||||
nsnull, // No owner
|
||||
owner,
|
||||
INTERNAL_LOAD_FLAGS_NONE, // Do not inherit owner from document (security-critical!)
|
||||
nsnull, // No window target
|
||||
contentType.get(), // Type hint
|
||||
|
|
|
@ -55,7 +55,7 @@ struct nsRect;
|
|||
%}
|
||||
[ref] native nsRect(nsRect);
|
||||
|
||||
[scriptable, uuid(542a98b9-2889-4922-aaf4-02b6056f4136)]
|
||||
[scriptable, uuid(9b4c7bf5-5e68-4406-9bb4-a4408c8e8bb5)]
|
||||
interface nsISHEntry : nsIHistoryEntry
|
||||
{
|
||||
/** URI for the document */
|
||||
|
@ -171,7 +171,8 @@ interface nsISHEntry : nsIHistoryEntry
|
|||
void create(in nsIURI URI, in AString title,
|
||||
in nsIInputStream inputStream,
|
||||
in nsILayoutHistoryState layoutHistoryState,
|
||||
in nsISupports cacheKey, in ACString contentType);
|
||||
in nsISupports cacheKey, in ACString contentType,
|
||||
in nsISupports owner);
|
||||
|
||||
nsISHEntry clone();
|
||||
|
||||
|
@ -182,6 +183,13 @@ interface nsISHEntry : nsIHistoryEntry
|
|||
nsSHEntry tree. This will differ from contentViewer in the case
|
||||
where a child nsSHEntry has the content viewer for this tree. */
|
||||
nsIContentViewer getAnyContentViewer(out nsISHEntry ownerEntry);
|
||||
|
||||
/**
|
||||
* Get the owner, if any, that was associated with the channel
|
||||
* that the document that was loaded to create this history entry
|
||||
* came from.
|
||||
*/
|
||||
readonly attribute nsISupports owner;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ nsSHEntry::nsSHEntry(const nsSHEntry &other)
|
|||
, mCacheKey(other.mCacheKey)
|
||||
, mParent(other.mParent)
|
||||
, mViewerBounds(0, 0, 0, 0)
|
||||
, mOwner(other.mOwner)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -405,13 +406,15 @@ NS_IMETHODIMP
|
|||
nsSHEntry::Create(nsIURI * aURI, const nsAString &aTitle,
|
||||
nsIInputStream * aInputStream,
|
||||
nsILayoutHistoryState * aLayoutHistoryState,
|
||||
nsISupports * aCacheKey, const nsACString& aContentType)
|
||||
nsISupports * aCacheKey, const nsACString& aContentType,
|
||||
nsISupports* aOwner)
|
||||
{
|
||||
mURI = aURI;
|
||||
mTitle = aTitle;
|
||||
mPostData = aInputStream;
|
||||
mCacheKey = aCacheKey;
|
||||
mContentType = aContentType;
|
||||
mOwner = aOwner;
|
||||
|
||||
// Set the LoadType by default to loadHistory during creation
|
||||
mLoadType = (PRUint32) nsIDocShellLoadInfo::loadHistory;
|
||||
|
@ -490,6 +493,13 @@ nsSHEntry::GetViewerBounds(nsRect &aBounds)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetOwner(nsISupports **aOwner)
|
||||
{
|
||||
NS_IF_ADDREF(*aOwner = mOwner);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsSHEntry: nsISHContainer
|
||||
//*****************************************************************************
|
||||
|
|
|
@ -104,6 +104,7 @@ private:
|
|||
nsRect mViewerBounds;
|
||||
nsVoidArray mChildShells;
|
||||
nsCOMPtr<nsISupportsArray> mRefreshURIList;
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
};
|
||||
|
||||
#endif /* nsSHEntry_h */
|
||||
|
|
Загрузка…
Ссылка в новой задаче