зеркало из https://github.com/mozilla/gecko-dev.git
Landing Dave Camp's fix for bug 362446. Add quotas to DOM storage. r=enndeakin@sympatico.ca, sr=jst@mozilla.org
This commit is contained in:
Родитель
ece1c4512f
Коммит
bcda25eda9
|
@ -103,5 +103,7 @@
|
||||||
#define NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM,1011)
|
#define NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM,1011)
|
||||||
#define NS_ERROR_DOM_BAD_URI NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM,1012)
|
#define NS_ERROR_DOM_BAD_URI NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM,1012)
|
||||||
#define NS_ERROR_DOM_RETVAL_UNDEFINED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM,1013)
|
#define NS_ERROR_DOM_RETVAL_UNDEFINED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM,1013)
|
||||||
|
#define NS_ERROR_DOM_QUOTA_REACHED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM,1014)
|
||||||
|
|
||||||
|
|
||||||
#endif // nsDOMError_h__
|
#endif // nsDOMError_h__
|
||||||
|
|
|
@ -99,6 +99,7 @@ DOM_MSG_DEF(NS_ERROR_DOM_PROP_ACCESS_DENIED, "Access to property denied")
|
||||||
DOM_MSG_DEF(NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED, "Access to XPConnect service denied")
|
DOM_MSG_DEF(NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED, "Access to XPConnect service denied")
|
||||||
DOM_MSG_DEF(NS_ERROR_DOM_BAD_URI, "Access to restricted URI denied")
|
DOM_MSG_DEF(NS_ERROR_DOM_BAD_URI, "Access to restricted URI denied")
|
||||||
DOM_MSG_DEF(NS_ERROR_DOM_RETVAL_UNDEFINED, "Return value is undefined")
|
DOM_MSG_DEF(NS_ERROR_DOM_RETVAL_UNDEFINED, "Return value is undefined")
|
||||||
|
DOM_MSG_DEF(NS_ERROR_DOM_QUOTA_REACHED, "Persistent storage maximum size reached")
|
||||||
|
|
||||||
/* common global codes (from nsError.h) */
|
/* common global codes (from nsError.h) */
|
||||||
|
|
||||||
|
|
|
@ -58,8 +58,11 @@ static const PRUint32 ASK_BEFORE_ACCEPT = 1;
|
||||||
static const PRUint32 ACCEPT_SESSION = 2;
|
static const PRUint32 ACCEPT_SESSION = 2;
|
||||||
static const PRUint32 BEHAVIOR_REJECT = 2;
|
static const PRUint32 BEHAVIOR_REJECT = 2;
|
||||||
|
|
||||||
|
static const PRUint32 DEFAULT_QUOTA = 5 * 1024;
|
||||||
|
|
||||||
static const char kPermissionType[] = "cookie";
|
static const char kPermissionType[] = "cookie";
|
||||||
static const char kStorageEnabled[] = "dom.storage.enabled";
|
static const char kStorageEnabled[] = "dom.storage.enabled";
|
||||||
|
static const char kDefaultQuota[] = "dom.storage.default_quota";
|
||||||
static const char kCookiesBehavior[] = "network.cookie.cookieBehavior";
|
static const char kCookiesBehavior[] = "network.cookie.cookieBehavior";
|
||||||
static const char kCookiesLifetimePolicy[] = "network.cookie.lifetimePolicy";
|
static const char kCookiesLifetimePolicy[] = "network.cookie.lifetimePolicy";
|
||||||
|
|
||||||
|
@ -100,6 +103,13 @@ IsCallerSecure()
|
||||||
return NS_SUCCEEDED(rv) && isHttps;
|
return NS_SUCCEEDED(rv) && isHttps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PRInt32
|
||||||
|
GetQuota(const nsAString &domain)
|
||||||
|
{
|
||||||
|
// FIXME: per-domain quotas?
|
||||||
|
return ((PRInt32)nsContentUtils::GetIntPref(kDefaultQuota, DEFAULT_QUOTA) * 1024);
|
||||||
|
}
|
||||||
|
|
||||||
nsSessionStorageEntry::nsSessionStorageEntry(KeyTypePointer aStr)
|
nsSessionStorageEntry::nsSessionStorageEntry(KeyTypePointer aStr)
|
||||||
: nsStringHashKey(aStr), mItem(nsnull)
|
: nsStringHashKey(aStr), mItem(nsnull)
|
||||||
{
|
{
|
||||||
|
@ -457,7 +467,8 @@ nsDOMStorage::GetItem(const nsAString& aKey, nsIDOMStorageItem **aItem)
|
||||||
else if (UseDB()) {
|
else if (UseDB()) {
|
||||||
PRBool secure;
|
PRBool secure;
|
||||||
nsAutoString value;
|
nsAutoString value;
|
||||||
nsresult rv = GetDBValue(aKey, value, &secure);
|
nsAutoString unused;
|
||||||
|
nsresult rv = GetDBValue(aKey, value, &secure, unused);
|
||||||
// return null if access isn't allowed or the key wasn't found
|
// return null if access isn't allowed or the key wasn't found
|
||||||
if (rv == NS_ERROR_DOM_SECURITY_ERR || rv == NS_ERROR_DOM_NOT_FOUND_ERR)
|
if (rv == NS_ERROR_DOM_SECURITY_ERR || rv == NS_ERROR_DOM_NOT_FOUND_ERR)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -544,14 +555,16 @@ NS_IMETHODIMP nsDOMStorage::RemoveItem(const nsAString& aKey)
|
||||||
nsresult rv = InitDB();
|
nsresult rv = InitDB();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsAutoString unused;
|
nsAutoString value;
|
||||||
PRBool secureItem;
|
PRBool secureItem;
|
||||||
rv = GetDBValue(aKey, unused, &secureItem);
|
nsAutoString owner;
|
||||||
|
rv = GetDBValue(aKey, value, &secureItem, owner);
|
||||||
if (rv == NS_ERROR_DOM_NOT_FOUND_ERR)
|
if (rv == NS_ERROR_DOM_NOT_FOUND_ERR)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = gStorageDB->RemoveKey(mDomain, aKey);
|
rv = gStorageDB->RemoveKey(mDomain, aKey, owner,
|
||||||
|
aKey.Length() + value.Length());
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
mItemsCached = PR_FALSE;
|
mItemsCached = PR_FALSE;
|
||||||
|
@ -622,7 +635,7 @@ nsDOMStorage::CacheKeysFromDB()
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsDOMStorage::GetDBValue(const nsAString& aKey, nsAString& aValue,
|
nsDOMStorage::GetDBValue(const nsAString& aKey, nsAString& aValue,
|
||||||
PRBool* aSecure)
|
PRBool* aSecure, nsAString& aOwner)
|
||||||
{
|
{
|
||||||
aValue.Truncate();
|
aValue.Truncate();
|
||||||
|
|
||||||
|
@ -634,7 +647,7 @@ nsDOMStorage::GetDBValue(const nsAString& aKey, nsAString& aValue,
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsAutoString value;
|
nsAutoString value;
|
||||||
rv = gStorageDB->GetKeyValue(mDomain, aKey, value, aSecure);
|
rv = gStorageDB->GetKeyValue(mDomain, aKey, value, aSecure, aOwner);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
|
@ -660,8 +673,32 @@ nsDOMStorage::SetDBValue(const nsAString& aKey,
|
||||||
nsresult rv = InitDB();
|
nsresult rv = InitDB();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsAutoString value;
|
// Get the current domain for quota enforcement
|
||||||
rv = gStorageDB->SetKey(mDomain, aKey, aValue, aSecure);
|
nsCOMPtr<nsIPrincipal> subjectPrincipal;
|
||||||
|
nsContentUtils::GetSecurityManager()->
|
||||||
|
GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
|
||||||
|
|
||||||
|
nsAutoString currentDomain;
|
||||||
|
|
||||||
|
if (subjectPrincipal) {
|
||||||
|
nsCOMPtr<nsIURI> uri;
|
||||||
|
rv = subjectPrincipal->GetURI(getter_AddRefs(uri));
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rv) && uri) {
|
||||||
|
nsCAutoString currentDomainAscii;
|
||||||
|
uri->GetAsciiHost(currentDomainAscii);
|
||||||
|
currentDomain = NS_ConvertUTF8toUTF16(currentDomainAscii);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDomain.IsEmpty()) {
|
||||||
|
return NS_ERROR_DOM_SECURITY_ERR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currentDomain = mDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = gStorageDB->SetKey(mDomain, aKey, aValue, aSecure,
|
||||||
|
currentDomain, GetQuota(currentDomain));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
mItemsCached = PR_FALSE;
|
mItemsCached = PR_FALSE;
|
||||||
|
@ -828,7 +865,7 @@ nsDOMStorageList::NamedItem(const nsAString& aDomain,
|
||||||
PRPackedBool sessionOnly;
|
PRPackedBool sessionOnly;
|
||||||
if (!nsDOMStorage::CanUseStorage(uri, &sessionOnly))
|
if (!nsDOMStorage::CanUseStorage(uri, &sessionOnly))
|
||||||
return NS_ERROR_DOM_SECURITY_ERR;
|
return NS_ERROR_DOM_SECURITY_ERR;
|
||||||
|
|
||||||
rv = uri->GetAsciiHost(currentDomain);
|
rv = uri->GetAsciiHost(currentDomain);
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SECURITY_ERR);
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SECURITY_ERR);
|
||||||
}
|
}
|
||||||
|
@ -1012,7 +1049,8 @@ nsDOMStorageItem::GetSecure(PRBool* aSecure)
|
||||||
|
|
||||||
if (mStorage->UseDB()) {
|
if (mStorage->UseDB()) {
|
||||||
nsAutoString value;
|
nsAutoString value;
|
||||||
return mStorage->GetDBValue(mKey, value, aSecure);
|
nsAutoString owner;
|
||||||
|
return mStorage->GetDBValue(mKey, value, aSecure, owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
*aSecure = IsSecure();
|
*aSecure = IsSecure();
|
||||||
|
@ -1044,7 +1082,8 @@ nsDOMStorageItem::GetValue(nsAString& aValue)
|
||||||
if (mStorage->UseDB()) {
|
if (mStorage->UseDB()) {
|
||||||
// GetDBValue checks the secure state so no need to do it here
|
// GetDBValue checks the secure state so no need to do it here
|
||||||
PRBool secure;
|
PRBool secure;
|
||||||
nsresult rv = mStorage->GetDBValue(mKey, aValue, &secure);
|
nsAutoString unused;
|
||||||
|
nsresult rv = mStorage->GetDBValue(mKey, aValue, &secure, unused);
|
||||||
return (rv == NS_ERROR_DOM_NOT_FOUND_ERR) ? NS_OK : rv;
|
return (rv == NS_ERROR_DOM_NOT_FOUND_ERR) ? NS_OK : rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,10 @@ public:
|
||||||
|
|
||||||
// retrieve the value and secure state corresponding to a key out of storage.
|
// retrieve the value and secure state corresponding to a key out of storage.
|
||||||
nsresult
|
nsresult
|
||||||
GetDBValue(const nsAString& aKey, nsAString& aValue, PRBool* aSecure);
|
GetDBValue(const nsAString& aKey,
|
||||||
|
nsAString& aValue,
|
||||||
|
PRBool* aSecure,
|
||||||
|
nsAString& aOwner);
|
||||||
|
|
||||||
// set the value corresponding to a key in the storage. If
|
// set the value corresponding to a key in the storage. If
|
||||||
// aSecure is false, then attempts to modify a secure value
|
// aSecure is false, then attempts to modify a secure value
|
||||||
|
|
|
@ -73,28 +73,63 @@ nsDOMStorageDB::Init()
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
PRBool exists;
|
PRBool exists;
|
||||||
rv = mConnection->TableExists(NS_LITERAL_CSTRING("moz_webappsstore"), &exists);
|
rv = mConnection->TableExists(NS_LITERAL_CSTRING("webappsstore"), &exists);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
if (! exists) {
|
if (! exists) {
|
||||||
rv = mConnection->ExecuteSimpleSQL(
|
rv = mConnection->ExecuteSimpleSQL(
|
||||||
NS_LITERAL_CSTRING("CREATE TABLE moz_webappsstore ("
|
NS_LITERAL_CSTRING("CREATE TABLE webappsstore ("
|
||||||
"domain TEXT, "
|
"domain TEXT, "
|
||||||
"key TEXT, "
|
"key TEXT, "
|
||||||
"value TEXT, "
|
"value TEXT, "
|
||||||
"secure INTEGER) "));
|
"secure INTEGER, "
|
||||||
|
"owner TEXT)"));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rv = mConnection->TableExists(NS_LITERAL_CSTRING("moz_webappsstore"),
|
||||||
|
&exists);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (exists) {
|
||||||
|
// upgrade an old store
|
||||||
|
|
||||||
|
// create a temporary index to handle dup checking
|
||||||
|
rv = mConnection->ExecuteSimpleSQL(
|
||||||
|
NS_LITERAL_CSTRING("CREATE UNIQUE INDEX webappsstore_tmp "
|
||||||
|
" ON webappsstore(domain, key)"));
|
||||||
|
|
||||||
|
// if the index can't be created, there are dup domain/key combos
|
||||||
|
// in moz_webappstore2, which indicates a bug elsewhere. Fail to upgrade
|
||||||
|
// in this case
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
rv = mConnection->ExecuteSimpleSQL(
|
||||||
|
NS_LITERAL_CSTRING("INSERT OR IGNORE INTO "
|
||||||
|
"webappsstore(domain, key, value, secure, owner) "
|
||||||
|
"SELECT domain, key, value, secure, domain "
|
||||||
|
"FROM moz_webappsstore"));
|
||||||
|
|
||||||
|
// try to drop the index even in case of an error
|
||||||
|
mConnection->ExecuteSimpleSQL(
|
||||||
|
NS_LITERAL_CSTRING("DROP INDEX webappsstore_tmp"));
|
||||||
|
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = mConnection->ExecuteSimpleSQL(
|
||||||
|
NS_LITERAL_CSTRING("DROP TABLE moz_webappsstore"));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// retrieve all keys associated with a domain
|
// retrieve all keys associated with a domain
|
||||||
rv = mConnection->CreateStatement(
|
rv = mConnection->CreateStatement(
|
||||||
NS_LITERAL_CSTRING("SELECT key, secure FROM moz_webappsstore "
|
NS_LITERAL_CSTRING("SELECT key, secure FROM webappsstore "
|
||||||
"WHERE domain = ?1"),
|
"WHERE domain = ?1"),
|
||||||
getter_AddRefs(mGetAllKeysStatement));
|
getter_AddRefs(mGetAllKeysStatement));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// retrieve a value given a domain and a key
|
// retrieve a value given a domain and a key
|
||||||
rv = mConnection->CreateStatement(
|
rv = mConnection->CreateStatement(
|
||||||
NS_LITERAL_CSTRING("SELECT value, secure FROM moz_webappsstore "
|
NS_LITERAL_CSTRING("SELECT value, secure, owner FROM webappsstore "
|
||||||
"WHERE domain = ?1 "
|
"WHERE domain = ?1 "
|
||||||
"AND key = ?2"),
|
"AND key = ?2"),
|
||||||
getter_AddRefs(mGetKeyValueStatement));
|
getter_AddRefs(mGetKeyValueStatement));
|
||||||
|
@ -102,22 +137,24 @@ nsDOMStorageDB::Init()
|
||||||
|
|
||||||
// insert a new key
|
// insert a new key
|
||||||
rv = mConnection->CreateStatement(
|
rv = mConnection->CreateStatement(
|
||||||
NS_LITERAL_CSTRING("INSERT INTO moz_webappsstore values (?1, ?2, ?3, ?4)"),
|
NS_LITERAL_CSTRING("INSERT INTO "
|
||||||
|
"webappsstore(domain, key, value, secure, owner) "
|
||||||
|
"VALUES (?1, ?2, ?3, ?4, ?5)"),
|
||||||
getter_AddRefs(mInsertKeyStatement));
|
getter_AddRefs(mInsertKeyStatement));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// update an existing key
|
// update an existing key
|
||||||
rv = mConnection->CreateStatement(
|
rv = mConnection->CreateStatement(
|
||||||
NS_LITERAL_CSTRING("UPDATE moz_webappsstore "
|
NS_LITERAL_CSTRING("UPDATE webappsstore "
|
||||||
"SET value = ?1, secure = ?2 "
|
"SET value = ?1, secure = ?2, owner = ?3"
|
||||||
"WHERE domain = ?3 "
|
"WHERE domain = ?4 "
|
||||||
"AND key = ?4 "),
|
"AND key = ?5 "),
|
||||||
getter_AddRefs(mUpdateKeyStatement));
|
getter_AddRefs(mUpdateKeyStatement));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// update the secure status of an existing key
|
// update the secure status of an existing key
|
||||||
rv = mConnection->CreateStatement(
|
rv = mConnection->CreateStatement(
|
||||||
NS_LITERAL_CSTRING("UPDATE moz_webappsstore "
|
NS_LITERAL_CSTRING("UPDATE webappsstore "
|
||||||
"SET secure = ?1 "
|
"SET secure = ?1 "
|
||||||
"WHERE domain = ?2 "
|
"WHERE domain = ?2 "
|
||||||
"AND key = ?3 "),
|
"AND key = ?3 "),
|
||||||
|
@ -126,7 +163,7 @@ nsDOMStorageDB::Init()
|
||||||
|
|
||||||
// remove a key
|
// remove a key
|
||||||
rv = mConnection->CreateStatement(
|
rv = mConnection->CreateStatement(
|
||||||
NS_LITERAL_CSTRING("DELETE FROM moz_webappsstore "
|
NS_LITERAL_CSTRING("DELETE FROM webappsstore "
|
||||||
"WHERE domain = ?1 "
|
"WHERE domain = ?1 "
|
||||||
"AND key = ?2"),
|
"AND key = ?2"),
|
||||||
getter_AddRefs(mRemoveKeyStatement));
|
getter_AddRefs(mRemoveKeyStatement));
|
||||||
|
@ -134,8 +171,16 @@ nsDOMStorageDB::Init()
|
||||||
|
|
||||||
// remove all keys
|
// remove all keys
|
||||||
rv = mConnection->CreateStatement(
|
rv = mConnection->CreateStatement(
|
||||||
NS_LITERAL_CSTRING("DELETE FROM moz_webappsstore"),
|
NS_LITERAL_CSTRING("DELETE FROM webappsstore"),
|
||||||
getter_AddRefs(mRemoveAllStatement));
|
getter_AddRefs(mRemoveAllStatement));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// check the usage for a given owner
|
||||||
|
rv = mConnection->CreateStatement(
|
||||||
|
NS_LITERAL_CSTRING("SELECT SUM(LENGTH(key) + LENGTH(value)) "
|
||||||
|
"FROM webappsstore "
|
||||||
|
"WHERE owner = ?1"),
|
||||||
|
getter_AddRefs(mGetUsageStatement));
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +224,8 @@ nsresult
|
||||||
nsDOMStorageDB::GetKeyValue(const nsAString& aDomain,
|
nsDOMStorageDB::GetKeyValue(const nsAString& aDomain,
|
||||||
const nsAString& aKey,
|
const nsAString& aKey,
|
||||||
nsAString& aValue,
|
nsAString& aValue,
|
||||||
PRBool* aSecure)
|
PRBool* aSecure,
|
||||||
|
nsAString& aOwner)
|
||||||
{
|
{
|
||||||
mozStorageStatementScoper scope(mGetKeyValueStatement);
|
mozStorageStatementScoper scope(mGetKeyValueStatement);
|
||||||
|
|
||||||
|
@ -199,6 +245,9 @@ nsDOMStorageDB::GetKeyValue(const nsAString& aDomain,
|
||||||
|
|
||||||
rv = mGetKeyValueStatement->GetInt32(1, &secureInt);
|
rv = mGetKeyValueStatement->GetInt32(1, &secureInt);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = mGetKeyValueStatement->GetString(2, aOwner);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rv = NS_ERROR_DOM_NOT_FOUND_ERR;
|
rv = NS_ERROR_DOM_NOT_FOUND_ERR;
|
||||||
|
@ -213,11 +262,26 @@ nsresult
|
||||||
nsDOMStorageDB::SetKey(const nsAString& aDomain,
|
nsDOMStorageDB::SetKey(const nsAString& aDomain,
|
||||||
const nsAString& aKey,
|
const nsAString& aKey,
|
||||||
const nsAString& aValue,
|
const nsAString& aValue,
|
||||||
PRBool aSecure)
|
PRBool aSecure,
|
||||||
|
const nsAString& aOwner,
|
||||||
|
PRInt32 aQuota)
|
||||||
{
|
{
|
||||||
mozStorageStatementScoper scope(mGetKeyValueStatement);
|
mozStorageStatementScoper scope(mGetKeyValueStatement);
|
||||||
|
|
||||||
|
PRInt32 usage = 0;
|
||||||
|
nsresult rv;
|
||||||
|
if (!aOwner.IsEmpty()) {
|
||||||
|
if (aOwner == mCachedOwner) {
|
||||||
|
usage = mCachedUsage;
|
||||||
|
} else {
|
||||||
|
rv = GetUsage(aOwner, &usage);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nsresult rv = mGetKeyValueStatement->BindStringParameter(0, aDomain);
|
usage += aKey.Length() + aValue.Length();
|
||||||
|
|
||||||
|
rv = mGetKeyValueStatement->BindStringParameter(0, aDomain);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
rv = mGetKeyValueStatement->BindStringParameter(1, aKey);
|
rv = mGetKeyValueStatement->BindStringParameter(1, aKey);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
@ -235,34 +299,67 @@ nsDOMStorageDB::SetKey(const nsAString& aDomain,
|
||||||
return NS_ERROR_DOM_SECURITY_ERR;
|
return NS_ERROR_DOM_SECURITY_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
mGetKeyValueStatement->Reset();
|
nsAutoString previousOwner;
|
||||||
|
rv = mGetKeyValueStatement->GetString(2, previousOwner);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (previousOwner == aOwner) {
|
||||||
|
nsAutoString previousValue;
|
||||||
|
rv = mGetKeyValueStatement->GetString(0, previousValue);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
usage -= aKey.Length() + previousValue.Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
mGetKeyValueStatement->Reset();
|
||||||
|
|
||||||
|
if (usage > aQuota) {
|
||||||
|
return NS_ERROR_DOM_QUOTA_REACHED;
|
||||||
|
}
|
||||||
|
|
||||||
mozStorageStatementScoper scopeupdate(mUpdateKeyStatement);
|
mozStorageStatementScoper scopeupdate(mUpdateKeyStatement);
|
||||||
|
|
||||||
rv = mUpdateKeyStatement->BindStringParameter(0, aValue);
|
rv = mUpdateKeyStatement->BindStringParameter(0, aValue);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
rv = mUpdateKeyStatement->BindInt32Parameter(1, aSecure);
|
rv = mUpdateKeyStatement->BindInt32Parameter(1, aSecure);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
rv = mUpdateKeyStatement->BindStringParameter(2, aDomain);
|
rv = mUpdateKeyStatement->BindStringParameter(2, aOwner);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
rv = mUpdateKeyStatement->BindStringParameter(3, aKey);
|
rv = mUpdateKeyStatement->BindStringParameter(3, aDomain);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
rv = mUpdateKeyStatement->BindStringParameter(4, aKey);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
return mUpdateKeyStatement->Execute();
|
rv = mUpdateKeyStatement->Execute();
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (usage > aQuota) {
|
||||||
|
return NS_ERROR_DOM_QUOTA_REACHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
mozStorageStatementScoper scopeinsert(mInsertKeyStatement);
|
||||||
|
|
||||||
|
rv = mInsertKeyStatement->BindStringParameter(0, aDomain);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
rv = mInsertKeyStatement->BindStringParameter(1, aKey);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
rv = mInsertKeyStatement->BindStringParameter(2, aValue);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
rv = mInsertKeyStatement->BindInt32Parameter(3, aSecure);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
rv = mInsertKeyStatement->BindStringParameter(4, aOwner);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = mInsertKeyStatement->Execute();
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
mozStorageStatementScoper scopeinsert(mInsertKeyStatement);
|
if (!aOwner.IsEmpty()) {
|
||||||
|
mCachedOwner = aOwner;
|
||||||
|
mCachedUsage = usage;
|
||||||
|
}
|
||||||
|
|
||||||
rv = mInsertKeyStatement->BindStringParameter(0, aDomain);
|
return NS_OK;
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
rv = mInsertKeyStatement->BindStringParameter(1, aKey);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
rv = mInsertKeyStatement->BindStringParameter(2, aValue);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
rv = mInsertKeyStatement->BindInt32Parameter(3, aSecure);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
return mInsertKeyStatement->Execute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -301,10 +398,16 @@ nsDOMStorageDB::SetSecure(const nsAString& aDomain,
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsDOMStorageDB::RemoveKey(const nsAString& aDomain,
|
nsDOMStorageDB::RemoveKey(const nsAString& aDomain,
|
||||||
const nsAString& aKey)
|
const nsAString& aKey,
|
||||||
|
const nsAString& aOwner,
|
||||||
|
PRInt32 aKeyUsage)
|
||||||
{
|
{
|
||||||
mozStorageStatementScoper scope(mRemoveKeyStatement);
|
mozStorageStatementScoper scope(mRemoveKeyStatement);
|
||||||
|
|
||||||
|
if (aOwner == mCachedOwner) {
|
||||||
|
mCachedUsage -= aKeyUsage;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult rv = mRemoveKeyStatement->BindStringParameter(0, aDomain);
|
nsresult rv = mRemoveKeyStatement->BindStringParameter(0, aDomain);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
rv = mRemoveKeyStatement->BindStringParameter(1, aKey);
|
rv = mRemoveKeyStatement->BindStringParameter(1, aKey);
|
||||||
|
@ -319,3 +422,23 @@ nsDOMStorageDB::RemoveAll()
|
||||||
mozStorageStatementScoper scope(mRemoveAllStatement);
|
mozStorageStatementScoper scope(mRemoveAllStatement);
|
||||||
return mRemoveAllStatement->Execute();
|
return mRemoveAllStatement->Execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsDOMStorageDB::GetUsage(const nsAString &aOwner, PRInt32 *aUsage)
|
||||||
|
{
|
||||||
|
mozStorageStatementScoper scope(mGetUsageStatement);
|
||||||
|
|
||||||
|
nsresult rv = mGetUsageStatement->BindStringParameter(0, aOwner);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
PRBool exists;
|
||||||
|
rv = mGetUsageStatement->ExecuteStep(&exists);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
*aUsage = 0;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mGetUsageStatement->GetInt32(0, aUsage);
|
||||||
|
}
|
||||||
|
|
|
@ -73,7 +73,8 @@ public:
|
||||||
GetKeyValue(const nsAString& aDomain,
|
GetKeyValue(const nsAString& aDomain,
|
||||||
const nsAString& aKey,
|
const nsAString& aKey,
|
||||||
nsAString& aValue,
|
nsAString& aValue,
|
||||||
PRBool* aSecure);
|
PRBool* aSecure,
|
||||||
|
nsAString& aOwner);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the value and secure flag for a key in storage.
|
* Set the value and secure flag for a key in storage.
|
||||||
|
@ -82,7 +83,9 @@ public:
|
||||||
SetKey(const nsAString& aDomain,
|
SetKey(const nsAString& aDomain,
|
||||||
const nsAString& aKey,
|
const nsAString& aKey,
|
||||||
const nsAString& aValue,
|
const nsAString& aValue,
|
||||||
PRBool aSecure);
|
PRBool aSecure,
|
||||||
|
const nsAString& aOwner,
|
||||||
|
PRInt32 aQuota);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the secure flag for a key in storage. Does nothing if the key was
|
* Set the secure flag for a key in storage. Does nothing if the key was
|
||||||
|
@ -98,7 +101,9 @@ public:
|
||||||
*/
|
*/
|
||||||
nsresult
|
nsresult
|
||||||
RemoveKey(const nsAString& aDomain,
|
RemoveKey(const nsAString& aDomain,
|
||||||
const nsAString& aKey);
|
const nsAString& aKey,
|
||||||
|
const nsAString& aOwner,
|
||||||
|
PRInt32 aKeyUsage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all keys from storage. Used when clearing storage.
|
* Removes all keys from storage. Used when clearing storage.
|
||||||
|
@ -108,6 +113,8 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
nsresult GetUsage(const nsAString &aOwner, PRInt32 *aUsage);
|
||||||
|
|
||||||
nsCOMPtr<mozIStorageConnection> mConnection;
|
nsCOMPtr<mozIStorageConnection> mConnection;
|
||||||
|
|
||||||
nsCOMPtr<mozIStorageStatement> mGetAllKeysStatement;
|
nsCOMPtr<mozIStorageStatement> mGetAllKeysStatement;
|
||||||
|
@ -117,6 +124,10 @@ protected:
|
||||||
nsCOMPtr<mozIStorageStatement> mSetSecureStatement;
|
nsCOMPtr<mozIStorageStatement> mSetSecureStatement;
|
||||||
nsCOMPtr<mozIStorageStatement> mRemoveKeyStatement;
|
nsCOMPtr<mozIStorageStatement> mRemoveKeyStatement;
|
||||||
nsCOMPtr<mozIStorageStatement> mRemoveAllStatement;
|
nsCOMPtr<mozIStorageStatement> mRemoveAllStatement;
|
||||||
|
nsCOMPtr<mozIStorageStatement> mGetUsageStatement;
|
||||||
|
|
||||||
|
nsAutoString mCachedOwner;
|
||||||
|
PRInt32 mCachedUsage;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsDOMStorageDB_h___ */
|
#endif /* nsDOMStorageDB_h___ */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче