Exemple #1
0
NS_IMETHODIMP nsDOMStorage::RemoveItem(const nsAString& aKey)
{
  if (!CacheStoragePermissions())
    return NS_ERROR_DOM_SECURITY_ERR;

  if (aKey.IsEmpty())
    return NS_OK;

  nsSessionStorageEntry *entry = mItems.GetEntry(aKey);

  if (entry && entry->mItem->IsSecure() && !IsCallerSecure()) {
    return NS_ERROR_DOM_SECURITY_ERR;
  }

  if (UseDB()) {
#ifdef MOZ_STORAGE
    nsresult rv = InitDB();
    NS_ENSURE_SUCCESS(rv, rv);

    nsAutoString value;
    PRBool secureItem;
    nsAutoString owner;
    rv = GetDBValue(aKey, value, &secureItem, owner);
    if (rv == NS_ERROR_DOM_NOT_FOUND_ERR)
      return NS_OK;
    NS_ENSURE_SUCCESS(rv, rv);

    rv = gStorageDB->RemoveKey(mDomain, aKey, owner,
                               aKey.Length() + value.Length());
    NS_ENSURE_SUCCESS(rv, rv);

    mItemsCached = PR_FALSE;

    BroadcastChangeNotification();
#endif
  }
  else if (entry) {
    // clear string as StorageItems may be referencing this item
    entry->mItem->ClearValue();

    BroadcastChangeNotification();
  }

  if (entry) {
    mItems.RawRemoveEntry(entry);
  }

  return NS_OK;
}
Exemple #2
0
nsresult
nsDOMStorage::Clear()
{
  if (!CacheStoragePermissions())
    return NS_ERROR_DOM_SECURITY_ERR;

  if (UseDB())
    CacheKeysFromDB();

  PRBool foundSecureItem = PR_FALSE;
  mItems.EnumerateEntries(CheckSecure, &foundSecureItem);

  if (foundSecureItem && !IsCallerSecure()) {
    return NS_ERROR_DOM_SECURITY_ERR;
  }

#ifdef MOZ_STORAGE
  if (UseDB()) {
    nsresult rv = InitDB();
    NS_ENSURE_SUCCESS(rv, rv);

    rv = gStorageDB->ClearStorage(this);
    NS_ENSURE_SUCCESS(rv, rv);
  }
#endif

  mItems.Clear();
  BroadcastChangeNotification();

  return NS_OK;
}
Exemple #3
0
nsresult
nsDOMStorage::SetDBValue(const nsAString& aKey,
                         const nsAString& aValue,
                         PRBool aSecure)
{
#ifdef MOZ_STORAGE
  if (!UseDB())
    return NS_OK;

  nsresult rv = InitDB();
  NS_ENSURE_SUCCESS(rv, rv);

  // Get the current domain for quota enforcement
  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);

  mItemsCached = PR_FALSE;

  BroadcastChangeNotification();
#endif

  return NS_OK;
}
Exemple #4
0
NS_IMETHODIMP
nsDOMStorage::SetItem(const nsAString& aKey, const nsAString& aData)
{
  if (!CacheStoragePermissions())
    return NS_ERROR_DOM_SECURITY_ERR;

  if (aKey.IsEmpty())
    return NS_OK;

  nsresult rv;
  nsRefPtr<nsDOMStorageItem> newitem = nsnull;
  nsSessionStorageEntry *entry = mItems.GetEntry(aKey);
  if (entry) {
    if (entry->mItem->IsSecure() && !IsCallerSecure()) {
      return NS_ERROR_DOM_SECURITY_ERR;
    }
    if (!UseDB()) {
      entry->mItem->SetValueInternal(aData);
    }
  }
  else {
    if (UseDB())
      newitem = new nsDOMStorageItem(this, aKey, aData, PR_FALSE);
    else 
      newitem = new nsDOMStorageItem(this, aKey, aData, PR_FALSE);
    if (!newitem)
      return NS_ERROR_OUT_OF_MEMORY;
  }

  if (UseDB()) {
    rv = SetDBValue(aKey, aData, IsCallerSecure());
    NS_ENSURE_SUCCESS(rv, rv);
  }

  if (newitem) {
    entry = mItems.PutEntry(aKey);
    NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
    entry->mItem = newitem;
  }

  // SetDBValue already calls BroadcastChangeNotification so don't do it again
  if (!UseDB())
    BroadcastChangeNotification();

  return NS_OK;
}
Exemple #5
0
nsresult
nsDOMStorage::SetDBValue(const nsAString& aKey,
                         const nsAString& aValue,
                         PRBool aSecure)
{
#ifdef MOZ_STORAGE
  if (!UseDB())
    return NS_OK;

  nsresult rv = InitDB();
  NS_ENSURE_SUCCESS(rv, rv);

  // Get the current domain for quota enforcement
  nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
  if (!ssm)
    return NS_ERROR_FAILURE;

  nsCOMPtr<nsIPrincipal> subjectPrincipal;
  ssm->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));

  nsCAutoString currentDomain;

  if (subjectPrincipal) {
    nsCOMPtr<nsIURI> unused;
    rv = GetPrincipalURIAndHost(subjectPrincipal, getter_AddRefs(unused),
                                currentDomain);
    // Don't bail out on NS_ERROR_DOM_SECURITY_ERR, since we want to allow
    // trusted file:// URIs below.
    if (NS_FAILED(rv) && rv != NS_ERROR_DOM_SECURITY_ERR) {
      return rv;
    }

    if (currentDomain.IsEmpty()) {
      // allow chrome urls and trusted file urls to write using
      // the storage's domain
      if (nsContentUtils::IsCallerTrustedForWrite())
        currentDomain = mDomain;
      else
        return NS_ERROR_DOM_SECURITY_ERR;
    }
  } else {
    currentDomain = mDomain;
  }

  PRInt32 quota;
  PRInt32 warnQuota;
  GetQuota(currentDomain, &quota, &warnQuota);

  PRInt32 usage;
  rv = gStorageDB->SetKey(this, aKey, aValue, aSecure, quota, &usage);
  NS_ENSURE_SUCCESS(rv, rv);

  mItemsCached = PR_FALSE;

  if (warnQuota >= 0 && usage > warnQuota) {
    // try to include the window that exceeded the warn quota
    nsCOMPtr<nsIDOMWindow> window;
    JSContext *cx;
    nsCOMPtr<nsIJSContextStack> stack =
      do_GetService("@mozilla.org/js/xpc/ContextStack;1");
    if (stack && NS_SUCCEEDED(stack->Peek(&cx)) && cx) {
      nsCOMPtr<nsIScriptContext> scriptContext;
      scriptContext = GetScriptContextFromJSContext(cx);
      if (scriptContext) {
        window = do_QueryInterface(scriptContext->GetGlobalObject());
      }
    }

    nsCOMPtr<nsIObserverService> os =
      do_GetService("@mozilla.org/observer-service;1");
    os->NotifyObservers(window, "dom-storage-warn-quota-exceeded",
                        NS_ConvertUTF8toUTF16(currentDomain).get());
  }

  BroadcastChangeNotification();
#endif

  return NS_OK;
}