Bug 341524, DOM storage should follow cookie prefs

This commit is contained in:
enndeakin%sympatico.ca 2006-08-19 01:21:58 +00:00
Родитель f40cf39e9a
Коммит 8769e463a9
8 изменённых файлов: 226 добавлений и 103 удалений

Просмотреть файл

@ -1671,16 +1671,13 @@ nsDocShell::HistoryPurged(PRInt32 aNumEntries)
}
NS_IMETHODIMP
nsDocShell::GetSessionStorageForDomain(const nsACString& aDomain,
nsIDOMStorage** aStorage)
nsDocShell::GetSessionStorageForURI(nsIURI* aURI,
nsIDOMStorage** aStorage)
{
NS_ENSURE_ARG_POINTER(aStorage);
*aStorage = nsnull;
if (aDomain.IsEmpty())
return NS_OK;
nsCOMPtr<nsIDocShellTreeItem> topItem;
nsresult rv = GetSameTypeRootTreeItem(getter_AddRefs(topItem));
if (NS_FAILED(rv))
@ -1691,9 +1688,16 @@ nsDocShell::GetSessionStorageForDomain(const nsACString& aDomain,
nsCOMPtr<nsIDocShell> topDocShell = do_QueryInterface(topItem);
if (topDocShell != this)
return topDocShell->GetSessionStorageForDomain(aDomain, aStorage);
if (!mStorages.Get(aDomain, aStorage)) {
return topDocShell->GetSessionStorageForURI(aURI, aStorage);
nsCAutoString currentDomain;
rv = aURI->GetAsciiHost(currentDomain);
NS_ENSURE_SUCCESS(rv, rv);
if (currentDomain.IsEmpty())
return NS_OK;
if (!mStorages.Get(currentDomain, aStorage)) {
nsCOMPtr<nsIDOMStorage> newstorage =
do_CreateInstance("@mozilla.org/dom/storage;1");
if (!newstorage)
@ -1702,9 +1706,9 @@ nsDocShell::GetSessionStorageForDomain(const nsACString& aDomain,
nsCOMPtr<nsPIDOMStorage> pistorage = do_QueryInterface(newstorage);
if (!pistorage)
return NS_ERROR_FAILURE;
pistorage->Init(NS_ConvertUTF8toUTF16(aDomain), PR_FALSE);
pistorage->Init(aURI, NS_ConvertUTF8toUTF16(currentDomain), PR_FALSE);
if (!mStorages.Put(aDomain, newstorage))
if (!mStorages.Put(currentDomain, newstorage))
return NS_ERROR_OUT_OF_MEMORY;
*aStorage = newstorage;
@ -6441,13 +6445,13 @@ nsDocShell::InternalLoad(nsIURI * aURI,
gethostrv |= aURI->GetAsciiHost(newDomain);
if (NS_SUCCEEDED(gethostrv) && thisDomain.Equals(newDomain)) {
nsCOMPtr<nsIDOMStorage> storage;
GetSessionStorageForDomain(thisDomain,
getter_AddRefs(storage));
GetSessionStorageForURI(currentCodebase,
getter_AddRefs(storage));
nsCOMPtr<nsPIDOMStorage> piStorage =
do_QueryInterface(storage);
if (piStorage) {
nsCOMPtr<nsIDOMStorage> newstorage =
piStorage->Clone();
piStorage->Clone(currentCodebase);
targetDocShell->AddSessionStorage(thisDomain,
newstorage);
}

Просмотреть файл

@ -68,7 +68,7 @@ interface nsILayoutHistoryState;
interface nsISecureBrowserUI;
interface nsIDOMStorage;
[scriptable, uuid(51241d7c-73c9-4b85-970c-bd4f91acfbcc)]
[scriptable, uuid(539355C0-F5C8-4929-A4AA-CB105E8F9997)]
interface nsIDocShell : nsISupports
{
/**
@ -417,7 +417,7 @@ interface nsIDocShell : nsISupports
*
* @param domain the domain of the storage object to retrieve
*/
nsIDOMStorage getSessionStorageForDomain(in ACString aDomain);
nsIDOMStorage getSessionStorageForURI(in nsIURI uri);
/*
* Add a WebApps session storage object to the docshell.

Просмотреть файл

@ -44,6 +44,7 @@
#include "nsTArray.h"
class nsIDOMStorage;
class nsIURI;
#define NS_PIDOMSTORAGE_IID \
{ 0x2fdbb82e, 0x4b47, 0x406a, \
@ -54,9 +55,9 @@ class nsPIDOMStorage : public nsISupports
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMSTORAGE_IID)
virtual void Init(const nsAString &aDomain, PRBool aUseDB) = 0;
virtual void Init(nsIURI* aURI, const nsAString &aDomain, PRBool aUseDB) = 0;
virtual already_AddRefed<nsIDOMStorage> Clone() = 0;
virtual already_AddRefed<nsIDOMStorage> Clone(nsIURI* aURI) = 0;
virtual nsTArray<nsString> *GetKeys() = 0;
};

Просмотреть файл

@ -5621,11 +5621,7 @@ nsGlobalWindow::GetSessionStorage(nsIDOMStorage ** aSessionStorage)
return NS_FAILED(rv) ? rv : NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
nsCAutoString currentDomain;
rv = codebase->GetAsciiHost(currentDomain);
NS_ENSURE_SUCCESS(rv, rv);
return docShell->GetSessionStorageForDomain(currentDomain, aSessionStorage);
return docShell->GetSessionStorageForURI(codebase, aSessionStorage);
}
NS_IMETHODIMP
@ -6139,11 +6135,11 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
if (NS_SUCCEEDED(gethostrv) && thisDomain.Equals(newDomain)) {
nsCOMPtr<nsIDOMStorage> storage;
mDocShell->GetSessionStorageForDomain(thisDomain,
getter_AddRefs(storage));
mDocShell->GetSessionStorageForURI(currentCodebase,
getter_AddRefs(storage));
nsCOMPtr<nsPIDOMStorage> piStorage = do_QueryInterface(storage);
if (piStorage) {
nsCOMPtr<nsIDOMStorage> newstorage = piStorage->Clone();
nsCOMPtr<nsIDOMStorage> newstorage = piStorage->Clone(newURI);
newDocShell->AddSessionStorage(thisDomain, newstorage);
}
}

Просмотреть файл

@ -50,6 +50,18 @@
#include "nsReadableUtils.h"
#include "nsIObserverService.h"
#include "nsNetUtil.h"
#include "nsIPrefBranch.h"
#include "nsICookiePermission.h"
#include "nsIPermissionManager.h"
static const PRUint32 ASK_BEFORE_ACCEPT = 1;
static const PRUint32 ACCEPT_SESSION = 2;
static const PRUint32 BEHAVIOR_REJECT = 2;
static const char kPermissionType[] = "cookie";
static const char kStorageEnabled[] = "dom.storage.enabled";
static const char kCookiesBehavior[] = "network.cookie.cookieBehavior";
static const char kCookiesLifetimePolicy[] = "network.cookie.lifetimePolicy";
//
// Helper that tells us whether the caller is secure or not.
@ -135,13 +147,17 @@ NS_NewDOMStorage(nsISupports* aOuter, REFNSIID aIID, void** aResult)
}
nsDOMStorage::nsDOMStorage()
: mUseDB(PR_FALSE), mItemsCached(PR_FALSE)
: mUseDB(PR_FALSE), mSessionOnly(PR_TRUE), mItemsCached(PR_FALSE)
{
mItems.Init(8);
}
nsDOMStorage::nsDOMStorage(const nsAString& aDomain, PRBool aUseDB)
: mUseDB(aUseDB), mItemsCached(PR_FALSE), mDomain(aDomain)
nsDOMStorage::nsDOMStorage(nsIURI* aURI, const nsAString& aDomain, PRBool aUseDB)
: mUseDB(aUseDB),
mSessionOnly(PR_TRUE),
mItemsCached(PR_FALSE),
mURI(aURI),
mDomain(aDomain)
{
#ifndef MOZ_STORAGE
mUseDB = PR_FALSE;
@ -155,8 +171,9 @@ nsDOMStorage::~nsDOMStorage()
}
void
nsDOMStorage::Init(const nsAString& aDomain, PRBool aUseDB)
nsDOMStorage::Init(nsIURI* aURI, const nsAString& aDomain, PRBool aUseDB)
{
mURI = aURI;
mDomain.Assign(aDomain);
#ifdef MOZ_STORAGE
mUseDB = aUseDB;
@ -165,6 +182,48 @@ nsDOMStorage::Init(const nsAString& aDomain, PRBool aUseDB)
#endif
}
//static
PRBool
nsDOMStorage::CanUseStorage(nsIURI* aURI, PRPackedBool* aSessionOnly)
{
// check if the domain can use storage. Downgrade to session only if only
// session storage may be used.
NS_ASSERTION(aURI && aSessionOnly, "null URI or session flag");
if (!nsContentUtils::GetBoolPref(kStorageEnabled))
return PR_FALSE;
nsCOMPtr<nsIPermissionManager> permissionManager =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
if (!permissionManager)
return PR_FALSE;
*aSessionOnly = PR_FALSE;
PRUint32 perm;
permissionManager->TestPermission(aURI, kPermissionType, &perm);
if (perm == nsIPermissionManager::DENY_ACTION)
return PR_FALSE;
if (perm == nsICookiePermission::ACCESS_SESSION) {
*aSessionOnly = PR_TRUE;
}
else if (perm != nsIPermissionManager::ALLOW_ACTION) {
PRUint32 cookieBehavior = nsContentUtils::GetIntPref(kCookiesBehavior);
PRUint32 lifetimePolicy = nsContentUtils::GetIntPref(kCookiesLifetimePolicy);
// treat ask as reject always
if (cookieBehavior == BEHAVIOR_REJECT || lifetimePolicy == ASK_BEFORE_ACCEPT)
return PR_FALSE;
if (lifetimePolicy == ACCEPT_SESSION)
*aSessionOnly = PR_TRUE;
}
return PR_TRUE;
}
class ItemCounterState
{
public:
@ -194,7 +253,10 @@ ItemCounter(nsSessionStorageEntry* aEntry, void* userArg)
NS_IMETHODIMP
nsDOMStorage::GetLength(PRUint32 *aLength)
{
if (mUseDB)
if (!CacheStoragePermissions())
return NS_ERROR_DOM_SECURITY_ERR;
if (UseDB())
CacheKeysFromDB();
ItemCounterState state(IsCallerSecure());
@ -253,7 +315,10 @@ nsDOMStorage::Key(PRUint32 aIndex, nsAString& aKey)
// maybe we need to have a lazily populated key array here or
// something?
if (mUseDB)
if (!CacheStoragePermissions())
return NS_ERROR_DOM_SECURITY_ERR;
if (UseDB())
CacheKeysFromDB();
IndexFinderData data(IsCallerSecure(), aIndex);
@ -274,6 +339,9 @@ nsDOMStorage::GetItem(const nsAString& aKey, nsIDOMStorageItem **aItem)
{
*aItem = nsnull;
if (!CacheStoragePermissions())
return NS_ERROR_DOM_SECURITY_ERR;
if (aKey.IsEmpty())
return NS_OK;
@ -285,7 +353,7 @@ nsDOMStorage::GetItem(const nsAString& aKey, nsIDOMStorageItem **aItem)
}
NS_ADDREF(*aItem = entry->mItem);
}
else if (mUseDB) {
else if (UseDB()) {
PRBool secure;
nsAutoString value;
nsresult rv = GetDBValue(aKey, value, &secure);
@ -295,7 +363,7 @@ nsDOMStorage::GetItem(const nsAString& aKey, nsIDOMStorageItem **aItem)
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<nsDOMStorageItem> newitem =
new nsDOMStorageItem(this, aKey, secure);
new nsDOMStorageItem(this, aKey, value, secure);
if (!newitem)
return NS_ERROR_OUT_OF_MEMORY;
@ -312,6 +380,9 @@ nsDOMStorage::GetItem(const nsAString& aKey, nsIDOMStorageItem **aItem)
NS_IMETHODIMP
nsDOMStorage::SetItem(const nsAString& aKey, const nsAString& aData)
{
if (!CacheStoragePermissions())
return NS_ERROR_DOM_SECURITY_ERR;
if (aKey.IsEmpty())
return NS_OK;
@ -322,21 +393,20 @@ nsDOMStorage::SetItem(const nsAString& aKey, const nsAString& aData)
if (entry->mItem->IsSecure() && !IsCallerSecure()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if (!mUseDB) {
rv = entry->mItem->SetValue(aData);
NS_ENSURE_SUCCESS(rv, rv);
if (!UseDB()) {
entry->mItem->SetValueInternal(aData);
}
}
else {
if (mUseDB)
newitem = new nsDOMStorageItem(this, aKey, PR_FALSE);
if (UseDB())
newitem = new nsDOMStorageItem(this, aKey, aData, PR_FALSE);
else
newitem = new nsDOMStorageItem(nsnull, aData, PR_FALSE);
newitem = new nsDOMStorageItem(this, aKey, aData, PR_FALSE);
if (!newitem)
return NS_ERROR_OUT_OF_MEMORY;
}
if (mUseDB) {
if (UseDB()) {
rv = SetDBValue(aKey, aData, IsCallerSecure());
NS_ENSURE_SUCCESS(rv, rv);
}
@ -348,7 +418,7 @@ nsDOMStorage::SetItem(const nsAString& aKey, const nsAString& aData)
}
// SetDBValue already calls BroadcastChangeNotification so don't do it again
if (!mUseDB)
if (!UseDB())
BroadcastChangeNotification();
return NS_OK;
@ -356,6 +426,9 @@ nsDOMStorage::SetItem(const nsAString& aKey, const nsAString& aData)
NS_IMETHODIMP nsDOMStorage::RemoveItem(const nsAString& aKey)
{
if (!CacheStoragePermissions())
return NS_ERROR_DOM_SECURITY_ERR;
if (aKey.IsEmpty())
return NS_OK;
@ -365,7 +438,7 @@ NS_IMETHODIMP nsDOMStorage::RemoveItem(const nsAString& aKey)
return NS_ERROR_DOM_SECURITY_ERR;
}
if (mUseDB) {
if (UseDB()) {
#ifdef MOZ_STORAGE
nsresult rv = InitDB();
NS_ENSURE_SUCCESS(rv, rv);
@ -453,8 +526,8 @@ nsDOMStorage::GetDBValue(const nsAString& aKey, nsAString& aValue,
aValue.Truncate();
#ifdef MOZ_STORAGE
NS_ASSERTION(mUseDB,
"Uh, we should only get here if we're using the database!");
if (!UseDB())
return NS_OK;
nsresult rv = InitDB();
NS_ENSURE_SUCCESS(rv, rv);
@ -480,8 +553,8 @@ nsDOMStorage::SetDBValue(const nsAString& aKey,
PRBool aSecure)
{
#ifdef MOZ_STORAGE
NS_ASSERTION(mUseDB,
"Uh, we should only get here if we're using the database!");
if (!UseDB())
return NS_OK;
nsresult rv = InitDB();
NS_ENSURE_SUCCESS(rv, rv);
@ -502,7 +575,7 @@ nsresult
nsDOMStorage::SetSecure(const nsAString& aKey, PRBool aSecure)
{
#ifdef MOZ_STORAGE
if (mUseDB) {
if (UseDB()) {
nsresult rv = InitDB();
NS_ENSURE_SUCCESS(rv, rv);
@ -537,15 +610,15 @@ CopyStorageItems(nsSessionStorageEntry* aEntry, void* userArg)
}
already_AddRefed<nsIDOMStorage>
nsDOMStorage::Clone()
nsDOMStorage::Clone(nsIURI* aURI)
{
if (mUseDB) {
if (UseDB()) {
NS_ERROR("Uh, don't clone a global storage object.");
return nsnull;
}
nsDOMStorage* storage = new nsDOMStorage(mDomain, PR_FALSE);
nsDOMStorage* storage = new nsDOMStorage(aURI, mDomain, PR_FALSE);
if (!storage)
return nsnull;
@ -576,7 +649,7 @@ KeysArrayBuilder(nsSessionStorageEntry* aEntry, void* userArg)
nsTArray<nsString> *
nsDOMStorage::GetKeys()
{
if (mUseDB)
if (UseDB())
CacheKeysFromDB();
KeysArrayBuilderStruct keystruct;
@ -603,7 +676,7 @@ nsDOMStorage::BroadcastChangeNotification()
// domain, but if it's a global storage object we do.
observerService->NotifyObservers((nsIDOMStorage *)this,
"dom-storage-changed",
mUseDB ? mDomain.get() : nsnull);
UseDB() ? mDomain.get() : nsnull);
}
//
@ -623,6 +696,8 @@ nsresult
nsDOMStorageList::NamedItem(const nsAString& aDomain,
nsIDOMStorage** aStorage)
{
*aStorage = nsnull;
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
if (!ssm)
return NS_ERROR_FAILURE;
@ -631,23 +706,27 @@ nsDOMStorageList::NamedItem(const nsAString& aDomain,
nsresult rv = ssm->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> systemPrincipal;
rv = ssm->GetSystemPrincipal(getter_AddRefs(systemPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> uri;
nsCAutoString currentDomain;
if (subjectPrincipal) {
nsCOMPtr<nsIURI> uri;
rv = subjectPrincipal->GetURI(getter_AddRefs(uri));
if (NS_SUCCEEDED(rv) && uri) {
PRPackedBool sessionOnly;
if (!nsDOMStorage::CanUseStorage(uri, &sessionOnly))
return NS_ERROR_DOM_SECURITY_ERR;
rv = uri->GetAsciiHost(currentDomain);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SECURITY_ERR);
}
}
if (subjectPrincipal == systemPrincipal || !currentDomain.IsEmpty()) {
return GetStorageForDomain(aDomain, NS_ConvertUTF8toUTF16(currentDomain),
subjectPrincipal == systemPrincipal, aStorage);
PRBool isSystem;
rv = ssm->SubjectPrincipalIsSystem(&isSystem);
NS_ENSURE_SUCCESS(rv, rv);
if (isSystem || !currentDomain.IsEmpty()) {
return GetStorageForDomain(uri, aDomain, NS_ConvertUTF8toUTF16(currentDomain),
isSystem, aStorage);
}
return NS_ERROR_DOM_SECURITY_ERR;
@ -690,11 +769,20 @@ nsDOMStorageList::CanAccessDomain(const nsAString& aRequestedDomain,
}
nsresult
nsDOMStorageList::GetStorageForDomain(const nsAString& aRequestedDomain,
nsDOMStorageList::GetStorageForDomain(nsIURI* aURI,
const nsAString& aRequestedDomain,
const nsAString& aCurrentDomain,
PRBool aNoCurrentDomainCheck,
nsIDOMStorage** aStorage)
{
// fail if the domain contains no periods.
// XXXndeakin update this when bug 342314 is fixed so that we can check
// for top-level domain names properly
nsAutoString trimmedDomain(aRequestedDomain);
trimmedDomain.Trim(".");
if (trimmedDomain.FindChar('.') == kNotFound)
return NS_ERROR_DOM_SECURITY_ERR;
if (!aNoCurrentDomainCheck && !CanAccessDomain(aRequestedDomain,
aCurrentDomain)) {
return NS_ERROR_DOM_SECURITY_ERR;
@ -717,7 +805,7 @@ nsDOMStorageList::GetStorageForDomain(const nsAString& aRequestedDomain,
// now have a valid domain, so look it up in the storage table
if (!mStorages.Get(usedDomain, aStorage)) {
nsCOMPtr<nsIDOMStorage> newstorage = new nsDOMStorage(usedDomain, PR_TRUE);
nsCOMPtr<nsIDOMStorage> newstorage = new nsDOMStorage(aURI, usedDomain, PR_TRUE);
if (!newstorage)
return NS_ERROR_OUT_OF_MEMORY;
@ -788,9 +876,11 @@ NS_IMPL_RELEASE(nsDOMStorageItem)
nsDOMStorageItem::nsDOMStorageItem(nsDOMStorage* aStorage,
const nsAString& aKey,
const nsAString& aValue,
PRBool aSecure)
: mSecure(aSecure),
mKeyOrValue(aKey),
mKey(aKey),
mValue(aValue),
mStorage(aStorage)
{
}
@ -802,13 +892,13 @@ nsDOMStorageItem::~nsDOMStorageItem()
NS_IMETHODIMP
nsDOMStorageItem::GetSecure(PRBool* aSecure)
{
if (!IsCallerSecure()) {
if (!mStorage->CacheStoragePermissions() || !IsCallerSecure()) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
if (mStorage) {
if (mStorage->UseDB()) {
nsAutoString value;
return mStorage->GetDBValue(mKeyOrValue, value, aSecure);
return mStorage->GetDBValue(mKey, value, aSecure);
}
*aSecure = IsSecure();
@ -818,12 +908,12 @@ nsDOMStorageItem::GetSecure(PRBool* aSecure)
NS_IMETHODIMP
nsDOMStorageItem::SetSecure(PRBool aSecure)
{
if (!IsCallerSecure()) {
if (!mStorage->CacheStoragePermissions() || !IsCallerSecure()) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
if (mStorage) {
nsresult rv = mStorage->SetSecure(mKeyOrValue, aSecure);
if (mStorage->UseDB()) {
nsresult rv = mStorage->SetSecure(mKey, aSecure);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -834,10 +924,13 @@ nsDOMStorageItem::SetSecure(PRBool aSecure)
NS_IMETHODIMP
nsDOMStorageItem::GetValue(nsAString& aValue)
{
if (mStorage) {
if (!mStorage->CacheStoragePermissions())
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
if (mStorage->UseDB()) {
// GetDBValue checks the secure state so no need to do it here
PRBool secure;
nsresult rv = mStorage->GetDBValue(mKeyOrValue, aValue, &secure);
nsresult rv = mStorage->GetDBValue(mKey, aValue, &secure);
return (rv == NS_ERROR_DOM_NOT_FOUND_ERR) ? NS_OK : rv;
}
@ -845,29 +938,31 @@ nsDOMStorageItem::GetValue(nsAString& aValue)
return NS_ERROR_DOM_SECURITY_ERR;
}
aValue = mKeyOrValue;
aValue = mValue;
return NS_OK;
}
NS_IMETHODIMP
nsDOMStorageItem::SetValue(const nsAString& aValue)
{
if (!mStorage->CacheStoragePermissions())
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
PRBool secureCaller = IsCallerSecure();
if (mStorage) {
if (mStorage->UseDB()) {
// SetDBValue() does the security checks for us.
return mStorage->SetDBValue(mKeyOrValue, aValue, secureCaller);
return mStorage->SetDBValue(mKey, aValue, secureCaller);
}
PRBool secureItem = IsSecure();
if (!secureCaller && secureItem) {
// The item is secure, but the caller isn't. Throw.
return NS_ERROR_DOM_SECURITY_ERR;
}
mKeyOrValue = aValue;
mValue = aValue;
mSecure = secureCaller;
return NS_OK;
}

Просмотреть файл

@ -73,7 +73,7 @@ class nsDOMStorage : public nsIDOMStorage,
{
public:
nsDOMStorage();
nsDOMStorage(const nsAString& aDomain, PRBool aUseDB);
nsDOMStorage(nsIURI* aURI, const nsAString& aDomain, PRBool aUseDB);
virtual ~nsDOMStorage();
// nsISupports
@ -83,13 +83,23 @@ public:
NS_DECL_NSIDOMSTORAGE
// nsPIDOMStorage
virtual void Init(const nsAString& aDomain, PRBool aUseDB);
virtual already_AddRefed<nsIDOMStorage> Clone();
virtual void Init(nsIURI* aURI, const nsAString& aDomain, PRBool aUseDB);
virtual already_AddRefed<nsIDOMStorage> Clone(nsIURI* aURI);
virtual nsTArray<nsString> *GetKeys();
// cache the keys from the database for faster lookup
nsresult
CacheKeysFromDB();
PRBool UseDB() { return mUseDB && !mSessionOnly; }
// cache whether storage may be used by aURI, and whether it is session
// only. If aURI is null, the uri associated with this storage (mURI)
// is checked. Returns true if storage may be used.
static PRBool
CanUseStorage(nsIURI* aURI, PRPackedBool* aSessionOnly);
PRBool
CacheStoragePermissions()
{
return CanUseStorage(mURI, &mSessionOnly);
}
// retrieve the value and secure state corresponding to a key out of storage.
nsresult
@ -111,13 +121,22 @@ protected:
nsresult InitDB();
// cache the keys from the database for faster lookup
nsresult CacheKeysFromDB();
void BroadcastChangeNotification();
// true if the storage database should be used for values
PRBool mUseDB;
PRPackedBool mUseDB;
// true if the preferences indicates that this storage should be session only
PRPackedBool mSessionOnly;
// true if items from the database are cached
PRBool mItemsCached;
PRPackedBool mItemsCached;
// the URI this store is associated with
nsCOMPtr<nsIURI> mURI;
// domain this store is associated with
nsAutoString mDomain;
@ -146,6 +165,15 @@ public:
// nsIDOMStorageList
NS_DECL_NSIDOMSTORAGELIST
/**
* Check whether aCurrentDomain has access to aRequestedDomain
*/
static PRBool
CanAccessDomain(const nsAString& aRequestedDomain,
const nsAString& aCurrentDomain);
protected:
/**
* Return the global nsIDOMStorage for a particular domain.
* aNoCurrentDomainCheck may be true to skip the domain comparison;
@ -157,7 +185,8 @@ public:
* @param aNoCurrentDomainCheck true to skip domain comparison
*/
nsresult
GetStorageForDomain(const nsAString& aRequestedDomain,
GetStorageForDomain(nsIURI* aURI,
const nsAString& aRequestedDomain,
const nsAString& aCurrentDomain,
PRBool aNoCurrentDomainCheck,
nsIDOMStorage** aStorage);
@ -169,15 +198,6 @@ public:
ConvertDomainToArray(const nsAString& aDomain,
nsStringArray* aArray);
/**
* Check whether aCurrentDomain has access to aRequestedDomain
*/
static PRBool
CanAccessDomain(const nsAString& aRequestedDomain,
const nsAString& aCurrentDomain);
protected:
nsInterfaceHashtable<nsStringHashKey, nsIDOMStorage> mStorages;
};
@ -187,6 +207,7 @@ class nsDOMStorageItem : public nsIDOMStorageItem,
public:
nsDOMStorageItem(nsDOMStorage* aStorage,
const nsAString& aKey,
const nsAString& aValue,
PRBool aSecure);
virtual ~nsDOMStorageItem();
@ -211,16 +232,17 @@ public:
const nsAString& GetValueInternal()
{
NS_ASSERTION(!mStorage, "Don't call this on global storage items!");
return mValue;
}
return mKeyOrValue;
const void SetValueInternal(const nsAString& aValue)
{
mValue = aValue;
}
void ClearValue()
{
NS_ASSERTION(!mStorage, "Don't call this on global storage items!");
mKeyOrValue.Truncate();
mValue.Truncate();
}
protected:
@ -228,8 +250,11 @@ protected:
// true if this value is for secure sites only
PRBool mSecure;
// value of the item, or key for the item if it came from the db.
nsString mKeyOrValue;
// key for the item
nsString mKey;
// value of the item
nsString mValue;
// If this item came from the db, mStorage points to the storage
// object where this item came from.

Просмотреть файл

@ -159,7 +159,7 @@ nsDOMStorageDB::GetAllKeys(const nsAString& aDomain,
nsSessionStorageEntry* entry = aKeys->PutEntry(key);
NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
entry->mItem = new nsDOMStorageItem(aStorage, key, secureInt);
entry->mItem = new nsDOMStorageItem(aStorage, key, EmptyString(), secureInt);
if (!entry->mItem) {
aKeys->RawRemoveEntry(entry);
return NS_ERROR_OUT_OF_MEMORY;

Просмотреть файл

@ -452,6 +452,8 @@ pref("dom.popup_maximum", 20);
pref("dom.popup_allowed_events", "change click dblclick mouseup reset submit");
pref("dom.disable_open_click_delay", 1000);
pref("dom.storage.enabled", true);
// Disable popups from plugins by default
// 0 = openAllowed
// 1 = openControlled