示例#1
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;
}
示例#2
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;
}