Bug 774585: Fix session storage to take app principals into account. r=mounir

This commit is contained in:
Jonas Sicking 2012-07-21 00:29:40 -07:00
parent 1711391e21
commit 2ac2ff6877
3 changed files with 24 additions and 83 deletions

View File

@ -52,20 +52,20 @@ let DomStorage = {
let shistory = aDocShell.sessionHistory;
for (let i = 0; i < shistory.count; i++) {
let uri = History.getUriForEntry(shistory, i);
let principal = History.getPrincipalForEntry(shistory, i, aDocShell);
if (!principal)
continue;
if (uri) {
// Check if we're allowed to store sessionStorage data.
let isHTTPS = uri.schemeIs("https");
if (aFullData || SessionStore.checkPrivacyLevel(isHTTPS, isPinned)) {
let host = History.getHostForURI(uri);
// Check if we're allowed to store sessionStorage data.
let isHTTPS = principal.URI && principal.URI.schemeIs("https");
if (aFullData || SessionStore.checkPrivacyLevel(isHTTPS, isPinned)) {
let origin = principal.extendedOrigin;
// Don't read a host twice.
if (!(host in data)) {
let hostData = this._readEntry(uri, aDocShell);
if (Object.keys(hostData).length) {
data[host] = hostData;
}
// Don't read a host twice.
if (!(origin in data)) {
let originData = this._readEntry(principal, aDocShell);
if (Object.keys(originData).length) {
data[origin] = originData;
}
}
}
@ -84,7 +84,8 @@ let DomStorage = {
write: function DomStorage_write(aDocShell, aStorageData) {
for (let [host, data] in Iterator(aStorageData)) {
let uri = Services.io.newURI(host, null, null);
let storage = aDocShell.getSessionStorageForURI(uri, "");
let principal = Services.scriptSecurityManager.getDocShellCodebasePrincipal(uri, aDocShell);
let storage = aDocShell.getSessionStorageForPrincipal(principal, "", true);
for (let [key, value] in Iterator(data)) {
try {
@ -104,19 +105,17 @@ let DomStorage = {
* @param aDocShell
* A tab's docshell (containing the sessionStorage)
*/
_readEntry: function DomStorage_readEntry(aURI, aDocShell) {
_readEntry: function DomStorage_readEntry(aPrincipal, aDocShell) {
let hostData = {};
let storage;
try {
let principal = Services.scriptSecurityManager.getCodebasePrincipal(aURI);
// Using getSessionStorageForPrincipal instead of
// getSessionStorageForURI just to be able to pass aCreate = false,
// that avoids creation of the sessionStorage object for the page
// earlier than the page really requires it. It was causing problems
// while accessing a storage when a page later changed its domain.
storage = aDocShell.getSessionStorageForPrincipal(principal, "", false);
storage = aDocShell.getSessionStorageForPrincipal(aPrincipal, "", false);
} catch (e) {
// sessionStorage might throw if it's turned off, see bug 458954
}
@ -143,30 +142,17 @@ let History = {
* That tab's session history
* @param aIndex
* The history entry's index
* @param aDocShell
* That tab's docshell
*/
getUriForEntry: function History_getUriForEntry(aHistory, aIndex) {
getPrincipalForEntry: function History_getPrincipalForEntry(aHistory,
aIndex,
aDocShell) {
try {
return aHistory.getEntryAtIndex(aIndex, false).URI;
return Services.scriptSecurityManager.getDocShellCodebasePrincipal(
aHistory.getEntryAtIndex(aIndex, false).URI, aDocShell);
} catch (e) {
// This might throw for some reason.
}
},
/**
* Returns the host of a given URI.
* @param aURI
* The URI for which to return the host
*/
getHostForURI: function History_getHostForURI(aURI) {
let host = aURI.spec;
try {
if (aURI.host)
host = aURI.prePath;
} catch (e) {
// This throws for host-less URIs (such as about: or jar:).
}
return host;
}
};

View File

@ -2510,40 +2510,6 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetSessionStorageForURI(nsIURI* aURI,
const nsAString& aDocumentURI,
nsIDOMStorage** aStorage)
{
return GetSessionStorageForURI(aURI, aDocumentURI, true, aStorage);
}
nsresult
nsDocShell::GetSessionStorageForURI(nsIURI* aURI,
const nsSubstring& aDocumentURI,
bool aCreate,
nsIDOMStorage** aStorage)
{
NS_ENSURE_ARG(aURI);
NS_ENSURE_ARG_POINTER(aStorage);
*aStorage = nsnull;
nsresult rv;
nsCOMPtr<nsIScriptSecurityManager> securityManager =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
// This is terrible hack and should go away along with this whole method.
nsCOMPtr<nsIPrincipal> principal;
rv = securityManager->GetCodebasePrincipal(aURI, getter_AddRefs(principal));
if (NS_FAILED(rv))
return rv;
return GetSessionStorageForPrincipal(principal, aDocumentURI, aCreate, aStorage);
}
nsresult
nsDocShell::AddSessionStorage(nsIPrincipal* aPrincipal,
nsIDOMStorage* aStorage)

View File

@ -39,7 +39,7 @@ interface nsIWebBrowserPrint;
interface nsIVariant;
interface nsIPrivacyTransitionObserver;
[scriptable, builtinclass, uuid(05802c0d-3315-4245-b72e-cf92eb3118a3)]
[scriptable, builtinclass, uuid(ef5a9aba-fe75-410c-a216-fe9b71a6661c)]
interface nsIDocShell : nsISupports
{
/**
@ -402,17 +402,6 @@ interface nsIDocShell : nsISupports
*/
void historyPurged(in long numEntries);
/*
* Retrieves the WebApps session storage object for the supplied domain.
* If it doesn't already exist, a new one will be created.
*
* @param uri the uri of the storage object to retrieve
* @param documentURI new storage will be created with reference to this
* document.documentURI that will appear in storage event
*/
nsIDOMStorage getSessionStorageForURI(in nsIURI uri,
in DOMString documentURI);
/*
* Retrieves the WebApps session storage object for the supplied principal.
*