Bug 1267910 - Part 1: Make the API getCookiesFromHost of the nsICookieManager2 OriginAttributes-aware. r=jdm
☠☠ backed out by f1f2644d3444 ☠ ☠
authorTim Huang <tihuang@mozilla.com>
Fri, 13 May 2016 02:29:00 -0400
changeset 298160 cc202e0ac0dd3401d340d1a8516a247a250c64b7
parent 298159 1ef294cb3b47138416d559cb2f36f35dc0de7151
child 298161 f8afc5cf9e0e90b6320e7436cbf6647b05cf1f1d
push id30273
push userkwierso@gmail.com
push dateFri, 20 May 2016 21:08:12 +0000
treeherdermozilla-central@c403ac05b8f4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
bugs1267910
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1267910 - Part 1: Make the API getCookiesFromHost of the nsICookieManager2 OriginAttributes-aware. r=jdm
netwerk/cookie/nsCookieService.cpp
netwerk/cookie/nsICookieManager2.idl
netwerk/locales/en-US/necko.properties
netwerk/test/TestCookie.cpp
--- a/netwerk/cookie/nsCookieService.cpp
+++ b/netwerk/cookie/nsCookieService.cpp
@@ -2255,26 +2255,98 @@ nsCookieService::GetEnumerator(nsISimple
     for (nsCookieEntry::IndexType i = 0; i < cookies.Length(); ++i) {
       cookieList.AppendObject(cookies[i]);
     }
   }
 
   return NS_NewArrayEnumerator(aEnumerator, cookieList);
 }
 
+static nsresult
+InitializeOriginAttributes(NeckoOriginAttributes* aAttrs,
+                           JS::HandleValue aOriginAttributes,
+                           JSContext* aCx,
+                           uint8_t aArgc,
+                           const char16_t* aAPI,
+                           const char16_t* aInterfaceSuffix)
+{
+  MOZ_ASSERT(aAttrs);
+  MOZ_ASSERT(aCx);
+  MOZ_ASSERT(aAPI);
+  MOZ_ASSERT(aInterfaceSuffix);
+
+  if (aArgc == 0) {
+    const char16_t* params[] = {
+      aAPI,
+      aInterfaceSuffix
+    };
+
+    // This is supposed to be temporary and in 1 or 2 releases we want to
+    // have originAttributes param as mandatory. But for now, we don't want to
+    // break existing addons, so we write a console message to inform the addon
+    // developers about it.
+    nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
+                                    NS_LITERAL_CSTRING("Cookie Manager"),
+                                    nullptr,
+                                    nsContentUtils::eNECKO_PROPERTIES,
+                                    "nsICookieManagerAPIDeprecated",
+                                    params, ArrayLength(params));
+  } else if (aArgc == 1) {
+    if (!aOriginAttributes.isObject() ||
+        !aAttrs->Init(aCx, aOriginAttributes)) {
+      return NS_ERROR_INVALID_ARG;
+    }
+  }
+
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 nsCookieService::Add(const nsACString &aHost,
                      const nsACString &aPath,
                      const nsACString &aName,
                      const nsACString &aValue,
                      bool              aIsSecure,
                      bool              aIsHttpOnly,
                      bool              aIsSession,
-                     int64_t           aExpiry)
+                     int64_t           aExpiry,
+                     JS::HandleValue   aOriginAttributes,
+                     JSContext*        aCx,
+                     uint8_t           aArgc)
 {
+  MOZ_ASSERT(aArgc == 0 || aArgc == 1);
+
+  NeckoOriginAttributes attrs;
+  nsresult rv = InitializeOriginAttributes(&attrs,
+                                           aOriginAttributes,
+                                           aCx,
+                                           aArgc,
+                                           MOZ_UTF16("nsICookieManager2.add()"),
+                                           MOZ_UTF16("2"));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return AddNative(aHost, aPath, aName, aValue, aIsSecure, aIsHttpOnly,
+                   aIsSession, aExpiry, &attrs);
+}
+
+NS_IMETHODIMP_(nsresult)
+nsCookieService::AddNative(const nsACString &aHost,
+                           const nsACString &aPath,
+                           const nsACString &aName,
+                           const nsACString &aValue,
+                           bool              aIsSecure,
+                           bool              aIsHttpOnly,
+                           bool              aIsSession,
+                           int64_t           aExpiry,
+                           NeckoOriginAttributes* aOriginAttributes)
+{
+  if (NS_WARN_IF(!aOriginAttributes)) {
+    return NS_ERROR_FAILURE;
+  }
+
   if (!mDBState) {
     NS_WARNING("No DBState! Profile already closed?");
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   // first, normalize the hostname, and fail if it contains illegal characters.
   nsAutoCString host(aHost);
   nsresult rv = NormalizeHost(host);
@@ -2282,17 +2354,17 @@ nsCookieService::Add(const nsACString &a
 
   // get the base domain for the host URI.
   // e.g. for "www.bbc.co.uk", this would be "bbc.co.uk".
   nsAutoCString baseDomain;
   rv = GetBaseDomainFromHost(host, baseDomain);
   NS_ENSURE_SUCCESS(rv, rv);
 
   int64_t currentTimeInUsec = PR_Now();
-  nsCookieKey key = DEFAULT_APP_KEY(baseDomain);
+  nsCookieKey key = nsCookieKey(baseDomain, *aOriginAttributes);
 
   RefPtr<nsCookie> cookie =
     nsCookie::Create(aName, aValue, host, aPath,
                      aExpiry,
                      currentTimeInUsec,
                      nsCookie::GenerateUniqueCreationTime(currentTimeInUsec),
                      aIsSession,
                      aIsSecure,
@@ -2365,34 +2437,26 @@ nsCookieService::Remove(const nsACString
                         const nsACString &aName,
                         const nsACString &aPath,
                         bool             aBlocked,
                         JS::HandleValue  aOriginAttributes,
                         JSContext*       aCx,
                         uint8_t          aArgc)
 {
   MOZ_ASSERT(aArgc == 0 || aArgc == 1);
-  if (aArgc == 0) {
-    // This is supposed to be temporary and in 1 or 2 releases we want to
-    // have originAttributes param as mandatory. But for now, we don't want to
-    // break existing addons, so we write a console message to inform the addon
-    // developers about it.
-    nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
-                                    NS_LITERAL_CSTRING("Cookie Manager"),
-                                    nullptr,
-                                    nsContentUtils::eNECKO_PROPERTIES,
-                                    "nsICookieManagerRemoveDeprecated");
-  }
 
   NeckoOriginAttributes attrs;
-  if (aArgc == 1 &&
-      (!aOriginAttributes.isObject() ||
-       !attrs.Init(aCx, aOriginAttributes))) {
-    return NS_ERROR_INVALID_ARG;
-  }
+  nsresult rv = InitializeOriginAttributes(&attrs,
+                                           aOriginAttributes,
+                                           aCx,
+                                           aArgc,
+                                           MOZ_UTF16("nsICookieManager.remove()"),
+                                           MOZ_UTF16(""));
+  NS_ENSURE_SUCCESS(rv, rv);
+
   return RemoveNative(aHost, aName, aPath, aBlocked, &attrs);
 }
 
 NS_IMETHODIMP_(nsresult)
 nsCookieService::RemoveNative(const nsACString &aHost,
                               const nsACString &aName,
                               const nsACString &aPath,
                               bool aBlocked,
@@ -4293,33 +4357,47 @@ nsCookieService::CountCookiesFromHost(co
   *aCountFromHost = entry ? entry->GetCookies().Length() : 0;
   return NS_OK;
 }
 
 // get an enumerator of cookies stored by a particular host. this is provided by the
 // nsICookieManager2 interface.
 NS_IMETHODIMP
 nsCookieService::GetCookiesFromHost(const nsACString     &aHost,
+                                    JS::HandleValue       aOriginAttributes,
+                                    JSContext*            aCx,
+                                    uint8_t               aArgc,
                                     nsISimpleEnumerator **aEnumerator)
 {
+  MOZ_ASSERT(aArgc == 0 || aArgc == 1);
+
   if (!mDBState) {
     NS_WARNING("No DBState! Profile already closed?");
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   // first, normalize the hostname, and fail if it contains illegal characters.
   nsAutoCString host(aHost);
   nsresult rv = NormalizeHost(host);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoCString baseDomain;
   rv = GetBaseDomainFromHost(host, baseDomain);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCookieKey key = DEFAULT_APP_KEY(baseDomain);
+  NeckoOriginAttributes attrs;
+  rv = InitializeOriginAttributes(&attrs,
+                                  aOriginAttributes,
+                                  aCx,
+                                  aArgc,
+                                  MOZ_UTF16("nsICookieManager2.getCookiesFromHost()"),
+                                  MOZ_UTF16("2"));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCookieKey key = nsCookieKey(baseDomain, attrs);
   EnsureReadDomain(key);
 
   nsCookieEntry *entry = mDBState->hostTable.GetEntry(key);
   if (!entry)
     return NS_NewEmptyEnumerator(aEnumerator);
 
   nsCOMArray<nsICookie> cookieList(mMaxCookiesPerHost);
   const nsCookieEntry::ArrayType &cookies = entry->GetCookies();
--- a/netwerk/cookie/nsICookieManager2.idl
+++ b/netwerk/cookie/nsICookieManager2.idl
@@ -41,25 +41,40 @@ interface nsICookieManager2 : nsICookieM
    *        modified by, an http connection.
    * @param aIsSession
    *        true if the cookie should exist for the current session only.
    *        see aExpiry.
    * @param aExpiry
    *        expiration date, in seconds since midnight (00:00:00), January 1,
    *        1970 UTC. note that expiry time will also be honored for session cookies;
    *        in this way, the more restrictive of the two will take effect.
+   * @param aOriginAttributes The originAttributes of this cookie. This
+   *                          attribute is optional to avoid breaking add-ons.
    */
+  [implicit_jscontext, optional_argc]
   void add(in AUTF8String aHost,
            in AUTF8String aPath,
            in ACString    aName,
            in ACString    aValue,
            in boolean     aIsSecure,
            in boolean     aIsHttpOnly,
            in boolean     aIsSession,
-           in int64_t     aExpiry);
+           in int64_t     aExpiry,
+           [optional] in jsval aOriginAttributes);
+
+  [notxpcom]
+  nsresult addNative(in AUTF8String aHost,
+                     in AUTF8String aPath,
+                     in ACString    aName,
+                     in ACString    aValue,
+                     in boolean     aIsSecure,
+                     in boolean     aIsHttpOnly,
+                     in boolean     aIsSession,
+                     in int64_t     aExpiry,
+                     in NeckoOriginAttributesPtr aOriginAttributes);
 
   /**
    * Find whether a given cookie already exists.
    *
    * @param aCookie
    *        the cookie to look for
    *
    * @return true if a cookie was found which matches the host, path, and name
@@ -87,22 +102,27 @@ interface nsICookieManager2 : nsICookieM
    * 'aHost'. Thus, for a host "weather.yahoo.com", the base domain would be
    * "yahoo.com", and any host or domain cookies for "yahoo.com" and its
    * subdomains would be returned.
    *
    * @param aHost
    *        the host string to search for, e.g. "google.com". this should consist
    *        of only the host portion of a URI. see @add for a description of
    *        acceptable host strings.
+   * @param aOriginAttributes The originAttributes of cookies that would be
+   *                          retrived. This attribute is optional to avoid
+   *                          breaking add-ons.
    *
    * @return an nsISimpleEnumerator of nsICookie2 objects.
    *
    * @see countCookiesFromHost
    */
-  nsISimpleEnumerator getCookiesFromHost(in AUTF8String aHost);
+  [implicit_jscontext, optional_argc]
+  nsISimpleEnumerator getCookiesFromHost(in AUTF8String aHost,
+                                         [optional] in jsval aOriginAttributes);
 
   /**
    * Import an old-style cookie file. Imported cookies will be added to the
    * existing database. If the database contains any cookies the same as those
    * being imported (i.e. domain, name, and path match), they will be replaced.
    *
    * @param aCookieFile the file to import, usually cookies.txt
    */
--- a/netwerk/locales/en-US/necko.properties
+++ b/netwerk/locales/en-US/necko.properties
@@ -39,10 +39,10 @@ SuperfluousAuth=You are about to log in to the site “%1$S” with the username “%2$S”, but the website does not require authentication. This may be an attempt to trick you.\n\nIs “%1$S” the site you want to visit?
 AutomaticAuth=You are about to log in to the site “%1$S” with the username “%2$S”.
 
 TrackingUriBlocked=The resource at “%1$S” was blocked because tracking protection is enabled.
 
 # LOCALIZATION NOTE (APIDeprecationWarning):
 # %1$S is the deprected API; %2$S is the API function that should be used.
 APIDeprecationWarning=Warning: ‘%1$S’ deprecated, please use ‘%2$S’
 
-# LOCALIZATION NOTE (nsICookieManagerRemoveDeprecated): don't localize nsICookieManager.remove() and originAttributes.
-nsICookieManagerRemoveDeprecated=“nsICookieManager.remove()” is changed. Update your code and pass the correct originAttributes. Read more on MDN: https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsICookieManager
+# LOCALIZATION NOTE (nsICookieManagerDeprecated): don't localize originAttributes.
+nsICookieManagerAPIDeprecated=“%1$S” is changed. Update your code and pass the correct originAttributes. Read more on MDN: https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsICookieManager%2$S
--- a/netwerk/test/TestCookie.cpp
+++ b/netwerk/test/TestCookie.cpp
@@ -592,43 +592,48 @@ main(int32_t argc, char *argv[])
 
       // *** nsICookieManager{2} interface tests
       sBuffer = PR_sprintf_append(sBuffer, "*** Beginning nsICookieManager{2} interface tests...\n");
       nsCOMPtr<nsICookieManager> cookieMgr = do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv0);
       if (NS_FAILED(rv0)) return -1;
       nsCOMPtr<nsICookieManager2> cookieMgr2 = do_QueryInterface(cookieMgr);
       if (!cookieMgr2) return -1;
 
+      mozilla::NeckoOriginAttributes attrs;
+
       // first, ensure a clean slate
       rv[0] = NS_SUCCEEDED(cookieMgr->RemoveAll());
       // add some cookies
-      rv[1] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("cookiemgr.test"), // domain
+      rv[1] = NS_SUCCEEDED(cookieMgr2->AddNative(NS_LITERAL_CSTRING("cookiemgr.test"), // domain
                                            NS_LITERAL_CSTRING("/foo"),           // path
                                            NS_LITERAL_CSTRING("test1"),          // name
                                            NS_LITERAL_CSTRING("yes"),            // value
                                            false,                             // is secure
                                            false,                             // is httponly
                                            true,                              // is session
-                                           INT64_MAX));                          // expiry time
-      rv[2] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("cookiemgr.test"), // domain
+                                           INT64_MAX,                            // expiry time
+                                           &attrs));                         // originAttributes
+      rv[2] = NS_SUCCEEDED(cookieMgr2->AddNative(NS_LITERAL_CSTRING("cookiemgr.test"), // domain
                                            NS_LITERAL_CSTRING("/foo"),           // path
                                            NS_LITERAL_CSTRING("test2"),          // name
                                            NS_LITERAL_CSTRING("yes"),            // value
                                            false,                             // is secure
                                            true,                              // is httponly
                                            true,                              // is session
-                                           PR_Now() / PR_USEC_PER_SEC + 2));     // expiry time
-      rv[3] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("new.domain"),     // domain
+                                           PR_Now() / PR_USEC_PER_SEC + 2,       // expiry time
+                                           &attrs));                         // originAttributes
+      rv[3] = NS_SUCCEEDED(cookieMgr2->AddNative(NS_LITERAL_CSTRING("new.domain"),     // domain
                                            NS_LITERAL_CSTRING("/rabbit"),        // path
                                            NS_LITERAL_CSTRING("test3"),          // name
                                            NS_LITERAL_CSTRING("yes"),            // value
                                            false,                             // is secure
                                            false,                             // is httponly
                                            true,                              // is session
-                                           INT64_MAX));                          // expiry time
+                                           INT64_MAX,                            // expiry time
+                                           &attrs));                         // originAttributes
       // confirm using enumerator
       nsCOMPtr<nsISimpleEnumerator> enumerator;
       rv[4] = NS_SUCCEEDED(cookieMgr->GetEnumerator(getter_AddRefs(enumerator)));
       int32_t i = 0;
       bool more;
       nsCOMPtr<nsICookie2> expiredCookie, newDomainCookie;
       while (NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && more) {
         nsCOMPtr<nsISupports> cookie;
@@ -654,33 +659,33 @@ main(int32_t argc, char *argv[])
       // check CountCookiesFromHost()
       uint32_t hostCookies = 0;
       rv[8] = NS_SUCCEEDED(cookieMgr2->CountCookiesFromHost(NS_LITERAL_CSTRING("cookiemgr.test"), &hostCookies)) &&
               hostCookies == 2;
       // check CookieExists() using the third cookie
       bool found;
       rv[9] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && found;
 
-      mozilla::NeckoOriginAttributes attrs;
 
       // remove the cookie, block it, and ensure it can't be added again
       rv[10] = NS_SUCCEEDED(cookieMgr->RemoveNative(NS_LITERAL_CSTRING("new.domain"), // domain
                                                     NS_LITERAL_CSTRING("test3"),      // name
                                                     NS_LITERAL_CSTRING("/rabbit"),    // path
                                                     true,                             // is blocked
                                                     &attrs));                         // originAttributes
       rv[11] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && !found;
-      rv[12] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("new.domain"),     // domain
+      rv[12] = NS_SUCCEEDED(cookieMgr2->AddNative(NS_LITERAL_CSTRING("new.domain"),     // domain
                                             NS_LITERAL_CSTRING("/rabbit"),        // path
                                             NS_LITERAL_CSTRING("test3"),          // name
                                             NS_LITERAL_CSTRING("yes"),            // value
                                             false,                             // is secure
                                             false,                             // is httponly
                                             true,                              // is session
-                                            INT64_MIN));                          // expiry time
+                                            INT64_MIN,                            // expiry time
+                                            &attrs));                         // originAttributes
       rv[13] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && !found;
       // sleep four seconds, to make sure the second cookie has expired
       PR_Sleep(4 * PR_TicksPerSecond());
       // check that both CountCookiesFromHost() and CookieExists() count the
       // expired cookie
       rv[14] = NS_SUCCEEDED(cookieMgr2->CountCookiesFromHost(NS_LITERAL_CSTRING("cookiemgr.test"), &hostCookies)) &&
               hostCookies == 2;
       rv[15] = NS_SUCCEEDED(cookieMgr2->CookieExists(expiredCookie, &found)) && found;