Bug 1259169 - nsICookieManager::remove() should be back-compatible, r=jdm
☠☠ backed out by b6b32554f9bb ☠ ☠
authorAndrea Marchesini <amarchesini@mozilla.com>
Fri, 08 Apr 2016 12:38:15 +0100
changeset 316208 74330da56b823ffb762d950af31249bb9c017682
parent 316207 606b864c48c33a5dbbeffe1b2af79ea3f7063761
child 316209 3c2c25159286ed063140f407ef84e68accf3ef5a
push id9480
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 17:12:58 +0000
treeherdermozilla-aurora@0d6a91c76a9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
bugs1259169
milestone48.0a1
Bug 1259169 - nsICookieManager::remove() should be back-compatible, r=jdm
browser/base/content/sanitize.js
browser/components/migration/MSMigrationUtils.jsm
browser/components/preferences/cookies.js
devtools/shared/gcli/commands/cookie.js
extensions/cookie/test/unit/test_bug526789.js
extensions/cookie/test/unit/test_cookies_profile_close.js
extensions/cookie/test/unit/test_cookies_read.js
netwerk/cookie/nsCookieService.cpp
netwerk/cookie/nsICookieManager.idl
netwerk/locales/en-US/necko.properties
netwerk/test/TestCookie.cpp
testing/marionette/driver.js
toolkit/components/extensions/ext-cookies.js
toolkit/components/extensions/test/mochitest/test_ext_cookies_permissions.html
toolkit/forgetaboutsite/ForgetAboutSite.jsm
toolkit/mozapps/extensions/test/xpinstall/browser_cookies2.js
toolkit/mozapps/extensions/test/xpinstall/browser_cookies3.js
toolkit/mozapps/extensions/test/xpinstall/browser_cookies4.js
--- a/browser/base/content/sanitize.js
+++ b/browser/base/content/sanitize.js
@@ -244,17 +244,17 @@ Sanitizer.prototype = {
             // Iterate through the cookies and delete any created after our cutoff.
             let cookiesEnum = cookieMgr.enumerator;
             while (cookiesEnum.hasMoreElements()) {
               let cookie = cookiesEnum.getNext().QueryInterface(Ci.nsICookie2);
 
               if (cookie.creationTime > range[0]) {
                 // This cookie was created after our cutoff, clear it
                 cookieMgr.remove(cookie.host, cookie.name, cookie.path,
-                                 cookie.originAttributes, false);
+                                 false, cookie.originAttributes);
 
                 if (++yieldCounter % YIELD_PERIOD == 0) {
                   yield new Promise(resolve => setTimeout(resolve, 0)); // Don't block the main thread too long
                 }
               }
             }
           }
           else {
--- a/browser/components/migration/MSMigrationUtils.jsm
+++ b/browser/components/migration/MSMigrationUtils.jsm
@@ -618,17 +618,17 @@ Cookies.prototype = {
       let hostLen = hostpath.indexOf("/");
       let host = hostpath.substr(0, hostLen);
       let path = hostpath.substr(hostLen);
 
       // For a non-null domain, assume it's what Mozilla considers
       // a domain cookie.  See bug 222343.
       if (host.length > 0) {
         // Fist delete any possible extant matching host cookie.
-        Services.cookies.remove(host, name, path, {}, false);
+        Services.cookies.remove(host, name, path, false, {});
         // Now make it a domain cookie.
         if (host[0] != "." && !hostIsIPAddress(host))
           host = "." + host;
       }
 
       // Fallback: expire in 1h (NB: time is in seconds since epoch, so we have
       // to divide the result of Date.now() (which is in milliseconds) by 1000).
       let expireTime = Math.floor(Date.now() / 1000) + 3600;
--- a/browser/components/preferences/cookies.js
+++ b/browser/components/preferences/cookies.js
@@ -586,17 +586,17 @@ var gCookiesWindow = {
     var psvc = Components.classes["@mozilla.org/preferences-service;1"]
                          .getService(Components.interfaces.nsIPrefBranch);
     var blockFutureCookies = false;
     if (psvc.prefHasUserValue("network.cookie.blockFutureCookies"))
       blockFutureCookies = psvc.getBoolPref("network.cookie.blockFutureCookies");
     for (var i = 0; i < deleteItems.length; ++i) {
       var item = deleteItems[i];
       this._cm.remove(item.host, item.name, item.path,
-                      item.originAttributes, blockFutureCookies);
+                      blockFutureCookies, item.originAttributes);
     }
   },
 
   deleteCookie: function () {
     // Selection Notes
     // - Selection always moves to *NEXT* adjacent item unless item
     //   is last child at a given level in which case it moves to *PREVIOUS*
     //   item
--- a/devtools/shared/gcli/commands/cookie.js
+++ b/devtools/shared/gcli/commands/cookie.js
@@ -128,17 +128,17 @@ exports.items = [
       host = sanitizeHost(host);
       let enm = cookieMgr.getCookiesFromHost(host);
 
       while (enm.hasMoreElements()) {
         let cookie = enm.getNext().QueryInterface(Ci.nsICookie);
         if (isCookieAtHost(cookie, host)) {
           if (cookie.name == args.name) {
             cookieMgr.remove(cookie.host, cookie.name, cookie.path,
-                             cookie.originAttributes, false);
+                             false, cookie.originAttributes);
           }
         }
       }
     }
   },
   {
     item: "converter",
     from: "cookies",
--- a/extensions/cookie/test/unit/test_bug526789.js
+++ b/extensions/cookie/test/unit/test_bug526789.js
@@ -23,31 +23,31 @@ function run_test() {
     cm.countCookiesFromHost("baz.com..");
   }, Cr.NS_ERROR_ILLEGAL_VALUE);
   do_check_throws(function() {
     cm.countCookiesFromHost("baz..com");
   }, Cr.NS_ERROR_ILLEGAL_VALUE);
   do_check_throws(function() {
     cm.countCookiesFromHost("..baz.com");
   }, Cr.NS_ERROR_ILLEGAL_VALUE);
-  cm.remove("BAZ.com.", "foo", "/", {}, false);
+  cm.remove("BAZ.com.", "foo", "/", false, {});
   do_check_eq(cm.countCookiesFromHost("baz.com"), 1);
-  cm.remove("baz.com", "foo", "/", {}, false);
+  cm.remove("baz.com", "foo", "/", false, {});
   do_check_eq(cm.countCookiesFromHost("baz.com"), 0);
 
   // Test that 'baz.com' and 'baz.com.' are treated differently
   cm.add("baz.com.", "/", "foo", "bar", false, false, true, expiry);
   do_check_eq(cm.countCookiesFromHost("baz.com"), 0);
   do_check_eq(cm.countCookiesFromHost("BAZ.com"), 0);
   do_check_eq(cm.countCookiesFromHost(".baz.com"), 0);
   do_check_eq(cm.countCookiesFromHost("baz.com."), 1);
   do_check_eq(cm.countCookiesFromHost(".baz.com."), 1);
-  cm.remove("baz.com", "foo", "/", {}, false);
+  cm.remove("baz.com", "foo", "/", false, {});
   do_check_eq(cm.countCookiesFromHost("baz.com."), 1);
-  cm.remove("baz.com.", "foo", "/", {}, false);
+  cm.remove("baz.com.", "foo", "/", false, {});
   do_check_eq(cm.countCookiesFromHost("baz.com."), 0);
 
   // test that domain cookies are illegal for IP addresses, aliases such as
   // 'localhost', and eTLD's such as 'co.uk'
   cm.add("192.168.0.1", "/", "foo", "bar", false, false, true, expiry);
   do_check_eq(cm.countCookiesFromHost("192.168.0.1"), 1);
   do_check_eq(cm.countCookiesFromHost("192.168.0.1."), 0);
   do_check_throws(function() {
@@ -169,20 +169,20 @@ function run_test() {
   // but a host of '.' doesn't
   cm.add("", "/", "foo2", "bar", false, false, true, expiry);
   do_check_eq(getCookieCount(), 1);
   do_check_throws(function() {
     cm.add(".", "/", "foo3", "bar", false, false, true, expiry);
   }, Cr.NS_ERROR_ILLEGAL_VALUE);
   do_check_eq(getCookieCount(), 1);
 
-  cm.remove("", "foo2", "/", {}, false);
+  cm.remove("", "foo2", "/", false, {});
   do_check_eq(getCookieCount(), 0);
   do_check_throws(function() {
-    cm.remove(".", "foo3", "/", {}, false);
+    cm.remove(".", "foo3", "/", false, {});
   }, Cr.NS_ERROR_ILLEGAL_VALUE);
 
   // test that the 'domain' attribute accepts a leading dot for IP addresses,
   // aliases such as 'localhost', and eTLD's such as 'co.uk'; but that the
   // resulting cookie is for the exact host only.
   testDomainCookie("http://192.168.0.1/", "192.168.0.1");
   testDomainCookie("http://localhost/", "localhost");
   testDomainCookie("http://co.uk/", "co.uk");
--- a/extensions/cookie/test/unit/test_cookies_profile_close.js
+++ b/extensions/cookie/test/unit/test_cookies_profile_close.js
@@ -53,17 +53,17 @@ function do_run_test() {
     Services.cookiemgr.enumerator;
   }, Cr.NS_ERROR_NOT_AVAILABLE);
 
   do_check_throws(function() {
     Services.cookiemgr.add("foo.com", "", "oh4", "hai", false, false, false, 0);
   }, Cr.NS_ERROR_NOT_AVAILABLE);
 
   do_check_throws(function() {
-    Services.cookiemgr.remove("foo.com", "", "oh4", {}, false);
+    Services.cookiemgr.remove("foo.com", "", "oh4", false, {});
   }, Cr.NS_ERROR_NOT_AVAILABLE);
 
   do_check_throws(function() {
     let file = profile.clone();
     file.append("cookies.txt");
     Services.cookiemgr.importCookies(file);
   }, Cr.NS_ERROR_NOT_AVAILABLE);
 
--- a/extensions/cookie/test/unit/test_cookies_read.js
+++ b/extensions/cookie/test/unit/test_cookies_read.js
@@ -81,21 +81,21 @@ function do_run_test() {
   // reload again, to make sure the additions were written correctly
   do_close_profile(test_generator);
   yield;
   do_load_profile();
 
   // remove some of the cookies, in both reverse and forward order
   for (let i = 100; i-- > 0; ) {
     let host = i.toString() + ".com";
-    Services.cookiemgr.remove(host, "oh", "/", {}, false);
+    Services.cookiemgr.remove(host, "oh", "/", false, {});
   }
   for (let i = CMAX - 100; i < CMAX; ++i) {
     let host = i.toString() + ".com";
-    Services.cookiemgr.remove(host, "oh", "/", {}, false);
+    Services.cookiemgr.remove(host, "oh", "/", false, {});
   }
 
   // check the count
   do_check_eq(do_count_cookies(), CMAX - 200);
 
   // reload again, to make sure the removals were written correctly
   do_close_profile(test_generator);
   yield;
--- a/netwerk/cookie/nsCookieService.cpp
+++ b/netwerk/cookie/nsCookieService.cpp
@@ -7,21 +7,23 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Likely.h"
 
 #include "mozilla/net/CookieServiceChild.h"
 #include "mozilla/net/NeckoCommon.h"
 
 #include "nsCookieService.h"
+#include "nsContentUtils.h"
 #include "nsIServiceManager.h"
 
 #include "nsIIOService.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
+#include "nsIScriptError.h"
 #include "nsICookiePermission.h"
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsIChannel.h"
 #include "nsIFile.h"
 #include "nsIObserverService.h"
 #include "nsILineInputStream.h"
 #include "nsIEffectiveTLDService.h"
@@ -2361,31 +2363,45 @@ nsCookieService::Remove(const nsACString
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCookieService::Remove(const nsACString &aHost,
                         const nsACString &aName,
                         const nsACString &aPath,
+                        bool             aBlocked,
                         JS::HandleValue  aOriginAttributes,
-                        bool             aBlocked,
-                        JSContext*       aCx)
+                        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;
   MOZ_ASSERT(attrs.Init(aCx, aOriginAttributes));
-  return RemoveNative(aHost, aName, aPath, &attrs, aBlocked);
+  return RemoveNative(aHost, aName, aPath, aBlocked, &attrs);
 }
 
 NS_IMETHODIMP_(nsresult)
 nsCookieService::RemoveNative(const nsACString &aHost,
                               const nsACString &aName,
                               const nsACString &aPath,
-                              NeckoOriginAttributes* aOriginAttributes,
-                              bool aBlocked)
+                              bool aBlocked,
+                              NeckoOriginAttributes* aOriginAttributes)
 {
   if (NS_WARN_IF(!aOriginAttributes)) {
     return NS_ERROR_FAILURE;
   }
 
   nsresult rv = Remove(aHost, *aOriginAttributes, aName, aPath, aBlocked);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
--- a/netwerk/cookie/nsICookieManager.idl
+++ b/netwerk/cookie/nsICookieManager.idl
@@ -42,26 +42,29 @@ interface nsICookieManager : nsISupports
    * directly from the desired nsICookie object.
    *
    * @param aHost The host or domain for which the cookie was set. @see
    *              nsICookieManager2::add for a description of acceptable host
    *              strings. If the target cookie is a domain cookie, a leading
    *              dot must be present.
    * @param aName The name specified in the cookie
    * @param aPath The path for which the cookie was set
-   * @param aOriginAttributes The originAttributes of this cookie
-   * @param aBlocked Indicates if cookies from this host should be permanently blocked
+   * @param aOriginAttributes The originAttributes of this cookie. This
+   *                          attribute is optional to avoid breaking add-ons.
+   *                          In 1 or 2 releases it will be mandatory: bug 1260399.
+   * @param aBlocked Indicates if cookies from this host should be permanently
+   *                 blocked.
    *
    */
-  [implicit_jscontext]
+  [implicit_jscontext, optional_argc]
   void remove(in AUTF8String   aHost,
               in ACString      aName,
               in AUTF8String   aPath,
-              in jsval         aOriginAttributes,
-              in boolean       aBlocked);
+              in boolean       aBlocked,
+              [optional] in jsval aOriginAttributes);
 
   [notxpcom]
   nsresult removeNative(in AUTF8String   aHost,
                         in ACString      aName,
                         in AUTF8String   aPath,
-                        in NeckoOriginAttributesPtr aOriginAttributes,
-                        in boolean       aBlocked);
+                        in boolean       aBlocked,
+                        in NeckoOriginAttributesPtr aOriginAttributes);
 };
--- a/netwerk/locales/en-US/necko.properties
+++ b/netwerk/locales/en-US/necko.properties
@@ -38,8 +38,11 @@ PhishingAuthAccept=I understand and will
 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/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsICookieManager'
--- a/netwerk/test/TestCookie.cpp
+++ b/netwerk/test/TestCookie.cpp
@@ -660,18 +660,18 @@ main(int32_t argc, char *argv[])
       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
-                                                    &attrs,                           // originAttributes
-                                                    true));                           // is blocked
+                                                    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
                                             NS_LITERAL_CSTRING("/rabbit"),        // path
                                             NS_LITERAL_CSTRING("test3"),          // name
                                             NS_LITERAL_CSTRING("yes"),            // value
                                             false,                             // is secure
                                             false,                             // is httponly
                                             true,                              // is session
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -2280,36 +2280,36 @@ GeckoDriver.prototype.getCookies = funct
 /** Delete all cookies that are visible to a document. */
 GeckoDriver.prototype.deleteAllCookies = function*(cmd, resp) {
   let cb = msg => {
     let cookie = msg.json;
     cookieManager.remove(
         cookie.host,
         cookie.name,
         cookie.path,
-        cookie.originAttributes,
-        false);
+        false,
+        cookie.originAttributes);
     return true;
   };
   this.mm.addMessageListener("Marionette:deleteCookie", cb);
   yield this.listener.deleteAllCookies();
   this.mm.removeMessageListener("Marionette:deleteCookie", cb);
 };
 
 /** Delete a cookie by name. */
 GeckoDriver.prototype.deleteCookie = function*(cmd, resp) {
   let cb = msg => {
     this.mm.removeMessageListener("Marionette:deleteCookie", cb);
     let cookie = msg.json;
     cookieManager.remove(
         cookie.host,
         cookie.name,
         cookie.path,
-        cookie.originAttributes,
-        false);
+        false,
+        cookie.originAttributes);
     return true;
   };
   this.mm.addMessageListener("Marionette:deleteCookie", cb);
   yield this.listener.deleteCookie(cmd.parameters.name);
 };
 
 /**
  * Close the current window, ending the session if it's the last
--- a/toolkit/components/extensions/ext-cookies.js
+++ b/toolkit/components/extensions/ext-cookies.js
@@ -290,17 +290,17 @@ extensions.registerSchemaAPI("cookies", 
         Services.cookies.add(cookieAttrs.host, path, name, value,
                              secure, httpOnly, isSession, expiry);
 
         return self.cookies.get(details);
       },
 
       remove: function(details) {
         for (let cookie of query(details, ["url", "name", "storeId"], extension)) {
-          Services.cookies.remove(cookie.host, cookie.name, cookie.path, cookie.originAttributes, false);
+          Services.cookies.remove(cookie.host, cookie.name, cookie.path, false, cookie.originAttributes);
           // Todo: could there be multiple per subdomain?
           return Promise.resolve({
             url: details.url,
             name: details.name,
             storeId: DEFAULT_STORE,
           });
         }
 
--- a/toolkit/components/extensions/test/mochitest/test_ext_cookies_permissions.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_cookies_permissions.html
@@ -112,17 +112,17 @@ function* testCookies(options) {
   cookieSvc.add(domain, "/", "deleted", "bar", options.secure, false, false, options.expiry);
 
 
   yield extension.startup();
 
   yield extension.awaitMessage("change-cookies");
   cookieSvc.add(domain, "/", "x", "y", options.secure, false, false, options.expiry);
   cookieSvc.add(domain, "/", "x", "z", options.secure, false, false, options.expiry);
-  cookieSvc.remove(domain, "x", "/", {}, false);
+  cookieSvc.remove(domain, "x", "/", false, {});
   extension.sendMessage("cookies-changed");
 
   yield extension.awaitFinish("cookie-permissions");
   yield extension.unload();
 
 
   function getCookies(host) {
     let cookies = [];
@@ -163,17 +163,17 @@ function* testCookies(options) {
 
     is(cookies[0].name, "deleted", "correct second cookie name");
 
     is(cookies[1].name, "foo", "correct cookie name");
     is(cookies[1].value, "bar", "correct cookie value");
   }
 
   for (let cookie of cookies) {
-    cookieSvc.remove(cookie.host, cookie.name, "/", {}, false);
+    cookieSvc.remove(cookie.host, cookie.name, "/", false, {});
   }
   // Make sure we don't silently poison subsequent tests if something goes wrong.
   is(getCookies(options.domain).length, 0, "cookies cleared");
 }
 
 
 add_task(function* init() {
   // We need to trigger a cookie eviction in order to test our batch delete
--- a/toolkit/forgetaboutsite/ForgetAboutSite.jsm
+++ b/toolkit/forgetaboutsite/ForgetAboutSite.jsm
@@ -72,17 +72,17 @@ this.ForgetAboutSite = {
     }
 
     // Cookies
     let cm = Cc["@mozilla.org/cookiemanager;1"].
              getService(Ci.nsICookieManager2);
     let enumerator = cm.getCookiesFromHost(aDomain);
     while (enumerator.hasMoreElements()) {
       let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
-      cm.remove(cookie.host, cookie.name, cookie.path, cookie.originAttributes, false);
+      cm.remove(cookie.host, cookie.name, cookie.path, false, cookie.originAttributes);
     }
 
     // EME
     let mps = Cc["@mozilla.org/gecko-media-plugin-service;1"].
                getService(Ci.mozIGeckoMediaPluginChromeService);
     mps.forgetThisSite(aDomain);
 
     // Plugin data
--- a/toolkit/mozapps/extensions/test/xpinstall/browser_cookies2.js
+++ b/toolkit/mozapps/extensions/test/xpinstall/browser_cookies2.js
@@ -26,15 +26,15 @@ function install_ended(install, addon) {
   install.cancel();
 }
 
 function finish_test(count) {
   is(count, 1, "1 Add-on should have been successfully installed");
 
   var cm = Components.classes["@mozilla.org/cookiemanager;1"]
                      .getService(Components.interfaces.nsICookieManager2);
-  cm.remove("example.com", "xpinstall", "/browser/" + RELATIVE_DIR, {}, false);
+  cm.remove("example.com", "xpinstall", "/browser/" + RELATIVE_DIR, false, {});
 
   Services.perms.remove(makeURI("http://example.com"), "install");
 
   gBrowser.removeCurrentTab();
   Harness.finish();
 }
--- a/toolkit/mozapps/extensions/test/xpinstall/browser_cookies3.js
+++ b/toolkit/mozapps/extensions/test/xpinstall/browser_cookies3.js
@@ -28,17 +28,17 @@ function install_ended(install, addon) {
   install.cancel();
 }
 
 function finish_test(count) {
   is(count, 1, "1 Add-on should have been successfully installed");
 
   var cm = Components.classes["@mozilla.org/cookiemanager;1"]
                      .getService(Components.interfaces.nsICookieManager2);
-  cm.remove("example.com", "xpinstall", "/browser/" + RELATIVE_DIR, {}, false);
+  cm.remove("example.com", "xpinstall", "/browser/" + RELATIVE_DIR, false, {});
 
   Services.prefs.clearUserPref("network.cookie.cookieBehavior");
 
   Services.perms.remove(makeURI("http://example.com"), "install");
 
   gBrowser.removeCurrentTab();
   Harness.finish();
 }
--- a/toolkit/mozapps/extensions/test/xpinstall/browser_cookies4.js
+++ b/toolkit/mozapps/extensions/test/xpinstall/browser_cookies4.js
@@ -28,16 +28,16 @@ function test() {
 function download_failed(install) {
   is(install.error, AddonManager.ERROR_NETWORK_FAILURE, "Install should fail");
 }
 
 function finish_test(count) {
   is(count, 0, "No add-ons should have been installed");
   var cm = Components.classes["@mozilla.org/cookiemanager;1"]
                      .getService(Components.interfaces.nsICookieManager2);
-  cm.remove("example.org", "xpinstall", "/browser/" + RELATIVE_DIR, {}, false);
+  cm.remove("example.org", "xpinstall", "/browser/" + RELATIVE_DIR, false, {});
 
   Services.prefs.clearUserPref("network.cookie.cookieBehavior");
   Services.perms.remove(makeURI("http://example.com"), "install");
 
   gBrowser.removeCurrentTab();
   Harness.finish();
 }