зеркало из https://github.com/mozilla/gecko-dev.git
Bug 592990 - about:home DOM storage is cleared with cookies and private browsing. r=mayhemer a=blocking
* * * fix bustage. a=bustage
This commit is contained in:
Родитель
07502e43a8
Коммит
2d2e2d9fdb
|
@ -183,16 +183,20 @@ IsOfflineAllowed(const nsACString &aDomain)
|
|||
// Returns two quotas - A hard limit for which adding data will be an error,
|
||||
// and a limit after which a warning event will be sent to the observer
|
||||
// service. The warn limit may be -1, in which case there will be no warning.
|
||||
// If aOverrideQuota is set, the larger offline apps quota is used and no
|
||||
// warning is sent.
|
||||
static PRUint32
|
||||
GetQuota(const nsACString &aDomain, PRInt32 *aQuota, PRInt32 *aWarnQuota)
|
||||
GetQuota(const nsACString &aDomain, PRInt32 *aQuota, PRInt32 *aWarnQuota,
|
||||
bool aOverrideQuota)
|
||||
{
|
||||
PRUint32 perm = GetOfflinePermission(aDomain);
|
||||
if (IS_PERMISSION_ALLOWED(perm)) {
|
||||
if (IS_PERMISSION_ALLOWED(perm) || aOverrideQuota) {
|
||||
// This is an offline app, give more space by default.
|
||||
*aQuota = ((PRInt32)nsContentUtils::GetIntPref(kOfflineAppQuota,
|
||||
DEFAULT_OFFLINE_APP_QUOTA) * 1024);
|
||||
|
||||
if (perm == nsIOfflineCacheUpdateService::ALLOW_NO_WARN) {
|
||||
if (perm == nsIOfflineCacheUpdateService::ALLOW_NO_WARN ||
|
||||
aOverrideQuota) {
|
||||
*aWarnQuota = -1;
|
||||
} else {
|
||||
*aWarnQuota = ((PRInt32)nsContentUtils::GetIntPref(kOfflineAppWarnQuota,
|
||||
|
@ -558,6 +562,7 @@ nsDOMStorage::nsDOMStorage()
|
|||
, mStorageType(nsPIDOMStorage::Unknown)
|
||||
, mItemsCached(PR_FALSE)
|
||||
, mEventBroadcaster(nsnull)
|
||||
, mCanUseChromePersist(false)
|
||||
{
|
||||
mSecurityChecker = this;
|
||||
mItems.Init(8);
|
||||
|
@ -575,6 +580,7 @@ nsDOMStorage::nsDOMStorage(nsDOMStorage& aThat)
|
|||
, mScopeDBKey(aThat.mScopeDBKey)
|
||||
#endif
|
||||
, mEventBroadcaster(nsnull)
|
||||
, mCanUseChromePersist(aThat.mCanUseChromePersist)
|
||||
{
|
||||
mSecurityChecker = this;
|
||||
mItems.Init(8);
|
||||
|
@ -677,6 +683,15 @@ nsDOMStorage::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aD
|
|||
#endif
|
||||
|
||||
mStorageType = LocalStorage;
|
||||
|
||||
nsCOMPtr<nsIURI> URI;
|
||||
if (NS_SUCCEEDED(aPrincipal->GetURI(getter_AddRefs(URI))) && URI) {
|
||||
PRBool isAbout;
|
||||
mCanUseChromePersist =
|
||||
(NS_SUCCEEDED(URI->SchemeIs("moz-safe-about", &isAbout)) && isAbout) ||
|
||||
(NS_SUCCEEDED(URI->SchemeIs("about", &isAbout)) && isAbout);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -810,6 +825,11 @@ nsDOMStorage::CacheStoragePermissions()
|
|||
return mSecurityChecker->CanAccess(subjectPrincipal);
|
||||
}
|
||||
|
||||
bool
|
||||
nsDOMStorage::CanUseChromePersist()
|
||||
{
|
||||
return mCanUseChromePersist;
|
||||
}
|
||||
|
||||
class ItemCounterState
|
||||
{
|
||||
|
@ -1252,7 +1272,8 @@ nsDOMStorage::SetDBValue(const nsAString& aKey,
|
|||
PRInt32 offlineAppPermission;
|
||||
PRInt32 quota;
|
||||
PRInt32 warnQuota;
|
||||
offlineAppPermission = GetQuota(mDomain, "a, &warnQuota);
|
||||
offlineAppPermission = GetQuota(mDomain, "a, &warnQuota,
|
||||
CanUseChromePersist());
|
||||
|
||||
PRInt32 usage;
|
||||
rv = gStorageDB->SetKey(this, aKey, aValue, aSecure, quota,
|
||||
|
@ -1982,18 +2003,18 @@ nsDOMStorageItem::ToString(nsAString& aStr)
|
|||
}
|
||||
|
||||
// Cycle collection implementation for nsDOMStorageEvent
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMStorageEvent)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMStorageEvent, nsDOMEvent)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mStorageArea)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMStorageEvent, nsDOMEvent)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mStorageArea)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsDOMStorageEvent, nsDOMEvent)
|
||||
NS_IMPL_RELEASE_INHERITED(nsDOMStorageEvent, nsDOMEvent)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMStorageEvent)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMStorageEvent, nsDOMEvent)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mStorageArea)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMStorageEvent, nsDOMEvent)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mStorageArea)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsDOMStorageEvent, nsDOMEvent)
|
||||
NS_IMPL_RELEASE_INHERITED(nsDOMStorageEvent, nsDOMEvent)
|
||||
|
||||
DOMCI_DATA(StorageEvent, nsDOMStorageEvent)
|
||||
|
||||
|
|
|
@ -175,6 +175,10 @@ public:
|
|||
return mSessionOnly;
|
||||
}
|
||||
|
||||
// Some privileged internal pages can use a persistent storage even in
|
||||
// session-only or private-browsing modes.
|
||||
bool CanUseChromePersist();
|
||||
|
||||
// Check whether storage may be used by the caller, and whether it
|
||||
// is session only. Returns true if storage may be used.
|
||||
static PRBool
|
||||
|
@ -266,6 +270,8 @@ protected:
|
|||
nsPIDOMStorage* mSecurityChecker;
|
||||
nsPIDOMStorage* mEventBroadcaster;
|
||||
|
||||
bool mCanUseChromePersist;
|
||||
|
||||
public:
|
||||
// e.g. "moc.rab.oof.:" or "moc.rab.oof.:http:80" depending
|
||||
// on association with a domain (globalStorage) or
|
||||
|
|
|
@ -74,7 +74,10 @@ nsDOMStorageDBWrapper::Init()
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
rv = mPersistentDB.Init();
|
||||
rv = mPersistentDB.Init(NS_LITERAL_STRING("webappsstore.sqlite"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mChromePersistentDB.Init(NS_LITERAL_STRING("chromeappsstore.sqlite"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mSessionOnlyDB.Init(&mPersistentDB);
|
||||
|
@ -90,6 +93,8 @@ nsresult
|
|||
nsDOMStorageDBWrapper::GetAllKeys(nsDOMStorage* aStorage,
|
||||
nsTHashtable<nsSessionStorageEntry>* aKeys)
|
||||
{
|
||||
if (aStorage->CanUseChromePersist())
|
||||
return mChromePersistentDB.GetAllKeys(aStorage, aKeys);
|
||||
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())
|
||||
return mPrivateBrowsingDB.GetAllKeys(aStorage, aKeys);
|
||||
if (aStorage->SessionOnly())
|
||||
|
@ -104,6 +109,8 @@ nsDOMStorageDBWrapper::GetKeyValue(nsDOMStorage* aStorage,
|
|||
nsAString& aValue,
|
||||
PRBool* aSecure)
|
||||
{
|
||||
if (aStorage->CanUseChromePersist())
|
||||
return mChromePersistentDB.GetKeyValue(aStorage, aKey, aValue, aSecure);
|
||||
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())
|
||||
return mPrivateBrowsingDB.GetKeyValue(aStorage, aKey, aValue, aSecure);
|
||||
if (aStorage->SessionOnly())
|
||||
|
@ -121,6 +128,9 @@ nsDOMStorageDBWrapper::SetKey(nsDOMStorage* aStorage,
|
|||
PRBool aExcludeOfflineFromUsage,
|
||||
PRInt32 *aNewUsage)
|
||||
{
|
||||
if (aStorage->CanUseChromePersist())
|
||||
return mChromePersistentDB.SetKey(aStorage, aKey, aValue, aSecure,
|
||||
aQuota, aExcludeOfflineFromUsage, aNewUsage);
|
||||
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())
|
||||
return mPrivateBrowsingDB.SetKey(aStorage, aKey, aValue, aSecure,
|
||||
aQuota, aExcludeOfflineFromUsage, aNewUsage);
|
||||
|
@ -137,6 +147,8 @@ nsDOMStorageDBWrapper::SetSecure(nsDOMStorage* aStorage,
|
|||
const nsAString& aKey,
|
||||
const PRBool aSecure)
|
||||
{
|
||||
if (aStorage->CanUseChromePersist())
|
||||
return mChromePersistentDB.SetSecure(aStorage, aKey, aSecure);
|
||||
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())
|
||||
return mPrivateBrowsingDB.SetSecure(aStorage, aKey, aSecure);
|
||||
if (aStorage->SessionOnly())
|
||||
|
@ -151,6 +163,8 @@ nsDOMStorageDBWrapper::RemoveKey(nsDOMStorage* aStorage,
|
|||
PRBool aExcludeOfflineFromUsage,
|
||||
PRInt32 aKeyUsage)
|
||||
{
|
||||
if (aStorage->CanUseChromePersist())
|
||||
return mChromePersistentDB.RemoveKey(aStorage, aKey, aExcludeOfflineFromUsage, aKeyUsage);
|
||||
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())
|
||||
return mPrivateBrowsingDB.RemoveKey(aStorage, aKey, aExcludeOfflineFromUsage, aKeyUsage);
|
||||
if (aStorage->SessionOnly())
|
||||
|
@ -162,6 +176,8 @@ nsDOMStorageDBWrapper::RemoveKey(nsDOMStorage* aStorage,
|
|||
nsresult
|
||||
nsDOMStorageDBWrapper::ClearStorage(nsDOMStorage* aStorage)
|
||||
{
|
||||
if (aStorage->CanUseChromePersist())
|
||||
return mChromePersistentDB.ClearStorage(aStorage);
|
||||
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())
|
||||
return mPrivateBrowsingDB.ClearStorage(aStorage);
|
||||
if (aStorage->SessionOnly())
|
||||
|
@ -249,6 +265,8 @@ nsresult
|
|||
nsDOMStorageDBWrapper::GetUsage(nsDOMStorage* aStorage,
|
||||
PRBool aExcludeOfflineFromUsage, PRInt32 *aUsage)
|
||||
{
|
||||
if (aStorage->CanUseChromePersist())
|
||||
return mChromePersistentDB.GetUsage(aStorage, aExcludeOfflineFromUsage, aUsage);
|
||||
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())
|
||||
return mPrivateBrowsingDB.GetUsage(aStorage, aExcludeOfflineFromUsage, aUsage);
|
||||
if (aStorage->SessionOnly())
|
||||
|
|
|
@ -217,6 +217,7 @@ public:
|
|||
nsACString& aDomain);
|
||||
|
||||
protected:
|
||||
nsDOMStoragePersistentDB mChromePersistentDB;
|
||||
nsDOMStoragePersistentDB mPersistentDB;
|
||||
nsDOMStorageMemoryDB mSessionOnlyDB;
|
||||
nsDOMStorageMemoryDB mPrivateBrowsingDB;
|
||||
|
|
|
@ -124,7 +124,7 @@ nsIsOfflineSQLFunction::OnFunctionCall(
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStoragePersistentDB::Init()
|
||||
nsDOMStoragePersistentDB::Init(const nsString& aDatabaseName)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
|
@ -132,7 +132,7 @@ nsDOMStoragePersistentDB::Init()
|
|||
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(storageFile));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = storageFile->Append(NS_LITERAL_STRING("webappsstore.sqlite"));
|
||||
rv = storageFile->Append(aDatabaseName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<mozIStorageService> service;
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
~nsDOMStoragePersistentDB() {}
|
||||
|
||||
nsresult
|
||||
Init();
|
||||
Init(const nsString& aDatabaseName);
|
||||
|
||||
/**
|
||||
* Retrieve a list of all the keys associated with a particular domain.
|
||||
|
|
|
@ -13,20 +13,99 @@ function run_test()
|
|||
testURI(Services.io.newURI("moz-safe-about:rights", null, null));
|
||||
}
|
||||
|
||||
function testURI(aURI) {
|
||||
function testURI(aURI)
|
||||
{
|
||||
print("Testing: " + aURI.spec);
|
||||
do_check_true(/about$/.test(aURI.scheme));
|
||||
let storage = getStorageForURI(aURI);
|
||||
storage.setItem("test-item", "test-value");
|
||||
print("Check that our value has been correctly stored.");
|
||||
do_check_eq(storage.length, 1);
|
||||
do_check_eq(storage.key(0), "test-item");
|
||||
do_check_eq(storage.getItem("test-item"), "test-value");
|
||||
|
||||
print("Check that our value is correctly removed.");
|
||||
storage.removeItem("test-item");
|
||||
do_check_eq(storage.length, 0);
|
||||
do_check_eq(storage.getItem("test-item"), null);
|
||||
|
||||
testURIWithPrivateBrowsing(aURI);
|
||||
|
||||
testURIWithClearCookies(aURI);
|
||||
}
|
||||
|
||||
function testURIWithPrivateBrowsing(aURI) {
|
||||
print("Testing with private browsing: " + aURI.spec);
|
||||
// Skip test if PB mode is not supported.
|
||||
if (!("@mozilla.org/privatebrowsing;1" in Components.classes)) {
|
||||
print("Skipped.");
|
||||
return;
|
||||
}
|
||||
|
||||
let storage = getStorageForURI(aURI);
|
||||
storage.setItem("test-item", "test-value");
|
||||
print("Check that our value has been correctly stored.");
|
||||
do_check_eq(storage.length, 1);
|
||||
do_check_eq(storage.key(0), "test-item");
|
||||
do_check_eq(storage.getItem("test-item"), "test-value");
|
||||
togglePBMode(true);
|
||||
do_check_eq(storage.length, 1);
|
||||
do_check_eq(storage.key(0), "test-item");
|
||||
do_check_eq(storage.getItem("test-item"), "test-value");
|
||||
|
||||
print("Check that our value is correctly removed.");
|
||||
storage.removeItem("test-item");
|
||||
do_check_eq(storage.length, 0);
|
||||
do_check_eq(storage.getItem("test-item"), null);
|
||||
togglePBMode(false);
|
||||
do_check_eq(storage.length, 0);
|
||||
do_check_eq(storage.getItem("test-item"), null);
|
||||
}
|
||||
|
||||
function testURIWithClearCookies(aURI) {
|
||||
let storage = getStorageForURI(aURI);
|
||||
storage.setItem("test-item", "test-value");
|
||||
print("Check that our value has been correctly stored.");
|
||||
do_check_eq(storage.length, 1);
|
||||
do_check_eq(storage.key(0), "test-item");
|
||||
do_check_eq(storage.getItem("test-item"), "test-value");
|
||||
|
||||
let dsm = Components.classes["@mozilla.org/dom/storagemanager;1"].
|
||||
getService(Components.interfaces.nsIObserver);
|
||||
dsm.observe(null, "cookie-changed", "cleared");
|
||||
|
||||
print("Check that our value is still stored.");
|
||||
do_check_eq(storage.length, 1);
|
||||
do_check_eq(storage.key(0), "test-item");
|
||||
do_check_eq(storage.getItem("test-item"), "test-value");
|
||||
|
||||
print("Check that we can explicitly clear value.");
|
||||
storage.clear();
|
||||
do_check_eq(storage.length, 0);
|
||||
do_check_eq(storage.getItem("test-item"), null);
|
||||
}
|
||||
|
||||
function getStorageForURI(aURI)
|
||||
{
|
||||
let principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"].
|
||||
getService(Components.interfaces.nsIScriptSecurityManager).
|
||||
getCodebasePrincipal(aURI);
|
||||
let dsm = Components.classes["@mozilla.org/dom/storagemanager;1"].
|
||||
getService(Components.interfaces.nsIDOMStorageManager);
|
||||
let storage = dsm.getLocalStorageForPrincipal(principal, "");
|
||||
storage.setItem("test-item", "test-value");
|
||||
print("Check that our value has been correctly stored.");
|
||||
do_check_eq(storage.getItem("test-item"), "test-value");
|
||||
storage.removeItem("test-item");
|
||||
print("Check that our value has been correctly removed.");
|
||||
do_check_eq(storage.getItem("test-item"), null);
|
||||
return dsm.getLocalStorageForPrincipal(principal, "");
|
||||
}
|
||||
|
||||
function togglePBMode(aEnable)
|
||||
{
|
||||
let pb = Components.classes["@mozilla.org/privatebrowsing;1"].
|
||||
getService(Components.interfaces.nsIPrivateBrowsingService);
|
||||
if (aEnable) {
|
||||
Services.prefs.setBoolPref("browser.privatebrowsing.keep_current_session",
|
||||
true);
|
||||
pb.privateBrowsingEnabled = true;
|
||||
} else {
|
||||
try {
|
||||
prefBranch.clearUserPref("browser.privatebrowsing.keep_current_session");
|
||||
} catch (ex) {}
|
||||
pb.privateBrowsingEnabled = false;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче