diff --git a/extensions/cookie/MANIFEST_IDL b/extensions/cookie/MANIFEST_IDL
index bd0b0599c52f..99bfde99a604 100644
--- a/extensions/cookie/MANIFEST_IDL
+++ b/extensions/cookie/MANIFEST_IDL
@@ -6,3 +6,4 @@ nsIPermissionManager.idl
nsICookieConsent.idl
nsICookieAcceptDialog.idl
nsICookiePromptService.idl
+nsICookiePermission.idl
diff --git a/extensions/cookie/Makefile.in b/extensions/cookie/Makefile.in
index 2bcd85857a93..2653c2c466cd 100644
--- a/extensions/cookie/Makefile.in
+++ b/extensions/cookie/Makefile.in
@@ -61,11 +61,10 @@ CPPSRCS = \
nsPermissionManager.cpp \
nsPopupWindowManager.cpp \
nsCookies.cpp \
- nsImages.cpp \
- nsPermissions.cpp \
nsUtils.cpp \
nsCookieHTTPNotify.cpp \
nsCookiePromptService.cpp \
+ nsCookiePermission.cpp \
$(NULL)
SDK_XPIDLSRCS = \
@@ -81,6 +80,7 @@ XPIDLSRCS = \
nsICookieAcceptDialog.idl \
nsICookiePromptService.idl \
nsICookieManager2.idl \
+ nsICookiePermission.idl \
$(NULL)
EXPORTS = \
diff --git a/extensions/cookie/macbuild/cookie.xml b/extensions/cookie/macbuild/cookie.xml
index 46a7fd201aa8..b889db9c1131 100644
--- a/extensions/cookie/macbuild/cookie.xml
+++ b/extensions/cookie/macbuild/cookie.xml
@@ -1006,13 +1006,6 @@
Text
Debug
-
- Name
- nsImages.cpp
- MacOS
- Text
- Debug
-
Name
nsImgManager.cpp
@@ -1057,7 +1050,7 @@
Name
- nsPermissions.cpp
+ nsCookiePermission.cpp
MacOS
Text
Debug
@@ -1126,11 +1119,6 @@
nsCookies.cpp
MacOS
-
- Name
- nsImages.cpp
- MacOS
-
Name
nsImgManager.cpp
@@ -1163,7 +1151,7 @@
Name
- nsPermissions.cpp
+ nsCookiePermission.cpp
MacOS
@@ -2126,13 +2114,6 @@
Text
Debug
-
- Name
- nsImages.cpp
- MacOS
- Text
- Debug
-
Name
nsImgManager.cpp
@@ -2177,7 +2158,7 @@
Name
- nsPermissions.cpp
+ nsCookiePermission.cpp
MacOS
Text
Debug
@@ -2246,11 +2227,6 @@
nsCookies.cpp
MacOS
-
- Name
- nsImages.cpp
- MacOS
-
Name
nsImgManager.cpp
@@ -2283,7 +2259,7 @@
Name
- nsPermissions.cpp
+ nsCookiePermission.cpp
MacOS
@@ -2332,12 +2308,6 @@
nsCookieService.cpp
MacOS
-
- Cookie.shlb
- Name
- nsImages.cpp
- MacOS
-
Cookie.shlb
Name
@@ -2377,7 +2347,7 @@
Cookie.shlb
Name
- nsPermissions.cpp
+ nsCookiePermission.cpp
MacOS
diff --git a/extensions/cookie/macbuild/cookieIDL.xml b/extensions/cookie/macbuild/cookieIDL.xml
index 36e1eef9a380..907620f97aa0 100644
--- a/extensions/cookie/macbuild/cookieIDL.xml
+++ b/extensions/cookie/macbuild/cookieIDL.xml
@@ -776,6 +776,13 @@
Text
+
+ Name
+ nsICookiePermission.idl
+ MacOS
+ Text
+
+
Name
nsICookiePromptService.idl
@@ -832,6 +839,11 @@
nsIPermissionManager.idl
MacOS
+
+ Name
+ nsICookiePermission.idl
+ MacOS
+
Name
nsICookiePromptService.idl
@@ -1567,6 +1579,13 @@
Text
+
+ Name
+ nsICookiePermission.idl
+ MacOS
+ Text
+
+
Name
nsICookiePromptService.idl
@@ -1623,6 +1642,11 @@
nsIPermissionManager.idl
MacOS
+
+ Name
+ nsICookiePermission.idl
+ MacOS
+
Name
nsICookiePromptService.idl
@@ -1691,6 +1715,12 @@
nsIPermissionManager.idl
MacOS
+
+ headers
+ Name
+ nsICookiePermission.idl
+ MacOS
+
headers
Name
diff --git a/extensions/cookie/nsCookiePermission.cpp b/extensions/cookie/nsCookiePermission.cpp
new file mode 100644
index 000000000000..48e592a25451
--- /dev/null
+++ b/extensions/cookie/nsCookiePermission.cpp
@@ -0,0 +1,122 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is cookie manager code.
+ *
+ * The Initial Developer of the Original Code is
+ * Michiel van Leeuwen (mvl@exedo.nl).
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#include "nsCookiePermission.h"
+#include "nsCookie.h"
+#include "nsICookieAcceptDialog.h"
+#include "nsIWindowWatcher.h"
+#include "nsIServiceManager.h"
+#include "nsString.h"
+#include "nsIDialogParamBlock.h"
+#include "nsArray.h"
+#include "nsCookiePromptService.h"
+
+/****************************************************************
+ ************************ nsCookiePermission ********************
+ ****************************************************************/
+
+static const PRUint32 kDefaultPolicy = nsIPermissionManager::ALLOW_ACTION;
+
+NS_IMPL_ISUPPORTS1(nsCookiePermission, nsICookiePermission);
+
+nsCookiePermission::nsCookiePermission()
+ : mPermissionManager(nsnull)
+{
+}
+
+nsCookiePermission::~nsCookiePermission()
+{
+}
+
+nsresult
+nsCookiePermission::Init()
+{
+ // Continue on an error. We can do a few things without a permission manager
+ mPermissionManager = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCookiePermission::TestPermission(nsIURI *aURI,
+ nsICookie *aCookie,
+ nsIDOMWindow *aParent,
+ PRInt32 aCookiesFromHost,
+ PRBool aChangingCookie,
+ PRBool aShowDialog,
+ PRBool *aPermission)
+{
+ NS_ASSERTION(aURI, "could not get uri");
+
+ nsresult rv;
+ *aPermission = kDefaultPolicy;
+
+ nsCAutoString hostPort;
+ aURI->GetHostPort(hostPort);
+ if (hostPort.IsEmpty())
+ return NS_OK;
+
+ PRUint32 listPermission = nsIPermissionManager::UNKNOWN_ACTION;
+ if (mPermissionManager) {
+ mPermissionManager->TestPermission(aURI, nsIPermissionManager::COOKIE_TYPE, &listPermission);
+ }
+
+ if (listPermission == nsIPermissionManager::UNKNOWN_ACTION) {
+ if (aShowDialog && aCookie) {
+ // we don't cache the cookiePromptService - it's not used often, so not worth the memory
+ nsCOMPtr cookiePromptService = do_GetService(NS_COOKIEPROMPTSERVICE_CONTRACTID, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ PRBool rememberDecision = PR_FALSE;
+
+ rv = cookiePromptService->
+ CookieDialog(nsnull, aCookie, hostPort,
+ aCookiesFromHost, aChangingCookie, &rememberDecision,
+ aPermission);
+ if (NS_FAILED(rv)) return rv;
+
+ if (rememberDecision && mPermissionManager) {
+ // Remember this decision
+ mPermissionManager->Add(aURI, nsIPermissionManager::COOKIE_TYPE, *aPermission);
+ }
+ }
+ } else {
+ *aPermission = (listPermission == nsIPermissionManager::ALLOW_ACTION);
+ }
+
+ return NS_OK;
+}
diff --git a/extensions/cookie/nsCookiePermission.h b/extensions/cookie/nsCookiePermission.h
new file mode 100644
index 000000000000..41ba4f21c036
--- /dev/null
+++ b/extensions/cookie/nsCookiePermission.h
@@ -0,0 +1,65 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is cookie manager code.
+ *
+ * The Initial Developer of the Original Code is
+ * Michiel van Leeuwen (mvl@exedo.nl).
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsCookiePermission_h__
+#define nsCookiePermission_h__
+
+#include "nsICookiePermission.h"
+#include "nsIDOMWindow.h"
+#include "nsCOMPtr.h"
+#include "nsIPermissionManager.h"
+
+#include "nsIURI.h"
+
+class nsCookiePermission : public nsICookiePermission
+{
+public:
+ nsCookiePermission();
+ virtual ~nsCookiePermission();
+ nsresult Init();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSICOOKIEPERMISSION
+
+private:
+ nsCOMPtr mPermissionManager;
+};
+
+// {CE002B28-92B7-4701-8621-CC925866FB87}
+#define NS_COOKIEPERMISSION_CID \
+ {0xEF565D0A, 0xAB9A, 0x4A13, {0x91, 0x60, 0x06, 0x44, 0xcd, 0xfd, 0x85, 0x9a }}
+
+#endif
diff --git a/extensions/cookie/nsCookiePromptService.cpp b/extensions/cookie/nsCookiePromptService.cpp
index d475d2bbba53..222b8a9d4ed9 100644
--- a/extensions/cookie/nsCookiePromptService.cpp
+++ b/extensions/cookie/nsCookiePromptService.cpp
@@ -63,7 +63,7 @@ nsCookiePromptService::CookieDialog(nsIDOMWindow *aParent,
const nsACString &aHostname,
PRInt32 aCookiesFromHost,
PRBool aChangingCookie,
- PRBool *aCheckValue,
+ PRBool *aRememberDecision,
PRBool *aAccept)
{
nsresult rv;
@@ -74,7 +74,6 @@ nsCookiePromptService::CookieDialog(nsIDOMWindow *aParent,
// since we're setting PRInt32's here, we have to sanitize the PRBool's first.
// (myBool != PR_FALSE) is guaranteed to return either 1 or 0.
block->SetInt(nsICookieAcceptDialog::ACCEPT_COOKIE, 1);
- block->SetInt(nsICookieAcceptDialog::REMEMBER_DECISION, *aCheckValue != PR_FALSE);
block->SetString(nsICookieAcceptDialog::HOSTNAME, NS_ConvertUTF8toUCS2(aHostname).get());
block->SetInt(nsICookieAcceptDialog::COOKIESFROMHOST, aCookiesFromHost);
block->SetInt(nsICookieAcceptDialog::CHANGINGCOOKIE, aChangingCookie != PR_FALSE);
@@ -111,7 +110,7 @@ nsCookiePromptService::CookieDialog(nsIDOMWindow *aParent,
*aAccept = (tempValue == 1);
block->GetInt(nsICookieAcceptDialog::REMEMBER_DECISION, &tempValue);
- *aCheckValue = (tempValue == 1);
+ *aRememberDecision = (tempValue == 1);
return rv;
}
diff --git a/extensions/cookie/nsCookieService.h b/extensions/cookie/nsCookieService.h
index 97c5f6cf4f46..6ce54ecc24de 100644
--- a/extensions/cookie/nsCookieService.h
+++ b/extensions/cookie/nsCookieService.h
@@ -49,11 +49,19 @@
#include "nsIObserverService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefBranchInternal.h"
-#include "nsPermissions.h"
+#include "nsXPIDLString.h"
////////////////////////////////////////////////////////////////////////////////
// nsCookiePrefObserver
+// enumerated type, used to specify default cookie behavior
+typedef enum {
+ PERMISSION_Accept,
+ PERMISSION_DontAcceptForeign,
+ PERMISSION_DontUse,
+ PERMISSION_P3P
+} PERMISSION_BehaviorEnum;
+
class nsCookiePrefObserver : public nsIObserver
, public nsSupportsWeakReference
{
diff --git a/extensions/cookie/nsCookies.cpp b/extensions/cookie/nsCookies.cpp
index 0d6ce028dc06..98e1515a5872 100644
--- a/extensions/cookie/nsCookies.cpp
+++ b/extensions/cookie/nsCookies.cpp
@@ -40,7 +40,8 @@
#include "nsCookies.h"
#include "nsCookieService.h"
-#include "nsPermissions.h"
+#include "nsICookiePermission.h"
+#include "nsIPermissionManager.h"
#include "nsIIOService.h"
#include "prprf.h"
#include "nsReadableUtils.h"
@@ -681,18 +682,27 @@ COOKIE_Remove(const nsACString &host,
if (cookieInList->path.Equals(path) &&
cookieInList->host.Equals(host) &&
cookieInList->name.Equals(name)) {
- // check if we need to add the host to the permissions blacklist
- if (blocked && NS_SUCCEEDED(PERMISSION_Read())) {
- // remove leading dot from host
- // we need this trickery since Permission_AddHost wants an nsAFlatCString
- // (and we want to avoid PromiseFlatCString()).
- // we should push this portion into the UI, it shouldn't live here in the backend.
- nsDependentCString hostWithoutDot(cookieInList->host.get(), cookieInList->host.Length());
- if (!cookieInList->host.IsEmpty() && cookieInList->host.First() == '.') {
- hostWithoutDot.Rebind(cookieInList->host.get() + 1, cookieInList->host.Length() - 1);
+ // check if we need to add the host to the permissions blacklist.
+ // we should push this portion into the UI, it shouldn't live here in the backend.
+ if (blocked) {
+ nsresult rv;
+ nsCOMPtr permissionManager = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
+
+ if (NS_SUCCEEDED(rv)) {
+ nsCOMPtr uri;
+ NS_NAMED_LITERAL_CSTRING(httpPrefix, "http://");
+ // remove leading dot from host
+ if (!cookieInList->host.IsEmpty() && cookieInList->host.First() == '.') {
+ rv = NS_NewURI(getter_AddRefs(uri), PromiseFlatCString(httpPrefix + Substring(cookieInList->host, 1, cookieInList->host.Length() - 1)));
+ } else {
+ rv = NS_NewURI(getter_AddRefs(uri), PromiseFlatCString(httpPrefix + cookieInList->host));
+ }
+
+ if (NS_SUCCEEDED(rv))
+ permissionManager->Add(uri,
+ nsIPermissionManager::COOKIE_TYPE,
+ nsIPermissionManager::DENY_ACTION);
}
-
- Permission_AddHost(hostWithoutDot, PR_FALSE, COOKIEPERMISSION, PR_TRUE);
}
sCookieList->RemoveElementAt(i);
@@ -1653,12 +1663,12 @@ COOKIE_ChangeFormat(cookie_CookieStruct *aCookie)
// to be processed
PRIVATE PRBool
cookie_SetCookieInternal(nsIURI *aHostURI,
- nsIPrompt *aPrompt,
nsDependentCString &aCookieHeader,
nsInt64 aServerTime,
nsCookieStatus aStatus,
nsCookiePolicy aPolicy)
{
+ nsresult rv;
// keep a |const char*| version of the unmodified aCookieHeader,
// for logging purposes
const char *cookieHeader = aCookieHeader.get();
@@ -1666,6 +1676,9 @@ cookie_SetCookieInternal(nsIURI *aHostURI,
nsInt64 expiryTime, currentTime = nsTime() / PR_USEC_PER_SEC;
PRBool isSession, foundCookie;
+ nsCOMPtr thisCookie;
+ nsCOMPtr cookiePermission;
+
// cookie stores all the attributes parsed from the cookie;
// expires and maxage are separate, because we have to process them to find the expiry.
// create a new cookie to store the attributes
@@ -1723,23 +1736,29 @@ cookie_SetCookieInternal(nsIURI *aHostURI,
goto failure;
}
+ // create a new nsICookie and copy the cookie data,
+ // for passing to the permission manager
+ thisCookie = COOKIE_ChangeFormat(cookie);
+
+ // we want to cache this ptr when we merge everything into nsCookieService
+ cookiePermission = do_GetService(NS_COOKIEPERMISSION_CONTRACTID, &rv);
// check permissions from site permission list, or ask the user,
// to determine if we can set the cookie
- if (NS_SUCCEEDED(PERMISSION_Read())) {
- // create a new nsICookie and copy the cookie data
- nsCOMPtr thisCookie = COOKIE_ChangeFormat(cookie);
-
- if (!thisCookie ||
- !Permission_Check(aPrompt, cookie->host.get(), COOKIEPERMISSION,
- gCookiePrefObserver->mCookiesAskPermission,
- thisCookie, countFromHost, foundCookie)) {
+ if (NS_SUCCEEDED(rv)) {
+ PRBool permission;
+ // we need to think about prompters/parent windows here - TestPermission
+ // needs one to prompt, so right now it has to fend for itself to get one
+ rv = cookiePermission->TestPermission(aHostURI, thisCookie, nsnull,
+ countFromHost, foundCookie,
+ gCookiePrefObserver->mCookiesAskPermission,
+ &permission);
+ if (!permission) {
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, cookieHeader, "cookies are blocked for this site");
goto failure;
}
}
// add the cookie to the list
- nsresult rv;
rv = COOKIE_Add(cookie, nsTime() / PR_USEC_PER_SEC, aHostURI, cookieHeader);
if (NS_FAILED(rv)) {
// no need to log a failure here, Add() does it for us
@@ -1809,7 +1828,7 @@ COOKIE_SetCookie(nsIURI *aHostURI,
// switch to a nice string type now, and process each cookie in the header
nsDependentCString cookieHeader(aCookieHeader);
- while (cookie_SetCookieInternal(aHostURI, aPrompt,
+ while (cookie_SetCookieInternal(aHostURI,
cookieHeader, serverTime,
cookieStatus, cookiePolicy));
}
diff --git a/extensions/cookie/nsICookiePermission.idl b/extensions/cookie/nsICookiePermission.idl
new file mode 100644
index 000000000000..e0f582fd0b47
--- /dev/null
+++ b/extensions/cookie/nsICookiePermission.idl
@@ -0,0 +1,70 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is cookie manager code.
+ *
+ * The Initial Developer of the Original Code is
+ * Michiel van Leeuwen (mvl@exedo.nl).
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.idl"
+
+/**
+ * An interface to test for cookie permissions
+ */
+
+interface nsICookie;
+interface nsIURI;
+interface nsIDOMWindow;
+
+[scriptable, uuid(EF565D0A-AB9A-4A13-9160-0644CDFD859A)]
+interface nsICookiePermission : nsISupports
+{
+ /**
+ * Test if a cookie from the given host should be accepted or denied
+ * @param uri the website to be tested
+ * @param cookie the cookie that wants to be set
+ * @param parent the parant window
+ * @param cookiesFromHost number of cookies this host already has set
+ * @param changingCookie are we changing this cookie?
+ * @param showDialog show a prompt to the user?
+ * @return whether the cookie has permission to be loaded
+ */
+ boolean testPermission(in nsIURI uri,
+ in nsICookie cookie,
+ in nsIDOMWindow parent,
+ in long cookiesFromHost,
+ in boolean changingCookie,
+ in boolean showDialog);
+};
+
+%{ C++
+#define NS_COOKIEPERMISSION_CONTRACTID "@mozilla.org/cookie/permission;1"
+%}
diff --git a/extensions/cookie/nsICookiePromptService.idl b/extensions/cookie/nsICookiePromptService.idl
index 6a448f054de0..0ec087207055 100644
--- a/extensions/cookie/nsICookiePromptService.idl
+++ b/extensions/cookie/nsICookiePromptService.idl
@@ -65,7 +65,7 @@ interface nsICookiePromptService : nsISupports
in ACString hostname,
in long cookiesFromHost,
in boolean changingCookie,
- inout boolean checkValue);
+ out boolean rememberDecision);
};
%{C++
diff --git a/extensions/cookie/nsIImgManager.idl b/extensions/cookie/nsIImgManager.idl
index 0b716326ecf3..b2dad944c0d9 100644
--- a/extensions/cookie/nsIImgManager.idl
+++ b/extensions/cookie/nsIImgManager.idl
@@ -36,10 +36,9 @@
*
* ***** END LICENSE BLOCK ***** */
-/*
-
- This file contains an interface to the Image Manager.
-
+/**
+ * This file contains an interface to the Image Manager,
+ * used for blocking images from user-specified sites.
*/
#include "nsISupports.idl"
@@ -49,12 +48,16 @@ interface nsIURI;
[scriptable, uuid(D60B3710-166D-11d5-A542-0010A401EB10)]
interface nsIImgManager : nsISupports
{
- void block(in nsIURI imageURL);
+ /**
+ * Test if the given image from URI can be loaded
+ * @param uri the uri of the image which wants to be loaded
+ * @param firstUri the uri of the document which tried to load the image
+ * @return whether the image has permission to be loaded
+ */
+ boolean testPermission(in nsIURI uri,
+ in nsIURI firstUri);
};
%{ C++
-// {D60B3710-166D-11d5-A542-0010A401EB10}
-#define NS_IMGMANAGER_CID \
-{ 0xd60b3710, 0x166d, 0x11d5, { 0xa5, 0x42, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 } }
#define NS_IMGMANAGER_CONTRACTID "@mozilla.org/imgmanager;1"
%}
diff --git a/extensions/cookie/nsIPermission.idl b/extensions/cookie/nsIPermission.idl
index 74f22d1e212f..8ebf10e3b711 100644
--- a/extensions/cookie/nsIPermission.idl
+++ b/extensions/cookie/nsIPermission.idl
@@ -24,24 +24,30 @@
[scriptable, uuid(28F16D80-157B-11d5-A542-0010A401EB10)]
/**
- This interface represents a "permission" object.
-*/
+ * This interface defines a "permission" object,
+ * used to specify allowed/blocked objects from
+ * user-specified sites (cookies, images etc).
+ */
-interface nsIPermission : nsISupports {
+interface nsIPermission : nsISupports
+{
+ /**
+ * The name of the host for which the permission is set
+ */
+ readonly attribute AUTF8String host;
- /* the name of the host */
- readonly attribute string host;
+ /**
+ * The type of permission (e.g., cookie, image, etc)
+ * (see nsIPermissionManager.idl for allowed values)
+ */
+ readonly attribute PRUint32 type;
- /* the type of permission (e.g., cookie, image, etc) */
- readonly attribute PRInt32 type;
-
- /* the permission */
- readonly attribute boolean capability;
+ /**
+ * The permission (see nsIPermissionManager.idl for allowed values)
+ */
+ readonly attribute PRUint32 capability;
};
%{ C++
-// {28F16D80-157B-11d5-A542-0010A401EB10}
-#define NS_PERMISSION_CID \
-{ 0x28f16d80, 0x157b, 0x11d5, { 0xa5, 0x42, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 } }
#define NS_PERMISSION_CONTRACTID "@mozilla.org/permission;1"
%}
diff --git a/extensions/cookie/nsIPermissionManager.idl b/extensions/cookie/nsIPermissionManager.idl
index de0ecd660d24..9ef54be3fd3b 100644
--- a/extensions/cookie/nsIPermissionManager.idl
+++ b/extensions/cookie/nsIPermissionManager.idl
@@ -1,4 +1,4 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -36,28 +36,81 @@
*
* ***** END LICENSE BLOCK ***** */
-/*
-
- This file contains an interface to the Permission Manager.
-
+/**
+ * This file contains an interface to the Permission Manager,
+ * used for blocking objects (cookies, images etc) from
+ * used-defined sites
+ *
+ * This service broadcasts a PERM_CHANGE_NOTIFICATION notification
+ * when any permission changes. You can add yourself as an observer.
*/
#include "nsISupports.idl"
#include "nsISimpleEnumerator.idl"
+interface nsIURI;
+interface nsIObserver;
+
[scriptable, uuid(4F6B5E00-0C36-11d5-A535-0010A401EB10)]
interface nsIPermissionManager : nsISupports
{
- void add(in AUTF8String objectURL, in boolean permission, in PRInt32 type);
- boolean testForBlocking(in AUTF8String objectURL, in PRInt32 type);
+ /**
+ * Allowed return values from the testPermission method
+ */
+ const PRUint32 UNKNOWN_ACTION = 0;
+ const PRUint32 ALLOW_ACTION = 1;
+ const PRUint32 DENY_ACTION = 2;
+
+ /**
+ * These values are the different types of permissions supported
+ */
+ const PRUint32 COOKIE_TYPE = 0;
+ const PRUint32 IMAGE_TYPE = 1;
+ const PRUint32 POPUP_TYPE = 2;
+
+ /**
+ * Add permission information for a given URI and permission type.
+ * @param uri is the website to add the permission for
+ * @param permission is one of the enumerated permission actions above
+ * @param type is one of the enumerated permission types above
+ */
+ void add(in nsIURI uri,
+ in PRUint32 type,
+ in PRUint32 permission);
+
+ /**
+ * Remove permission information for a given URI and permission type.
+ * Note that this method takes a host string, not an nsIURI.
+ * @param host is the host to remove the permission for
+ * @param type is one of the enumerated permission types above
+ */
+ void remove(in AUTF8String host,
+ in PRUint32 type);
+
+ /**
+ * Clear permission information for all websites.
+ */
void removeAll();
+
+ /**
+ * Test whether a website has permission to perform the given action.
+ * @param uri the website to be tested
+ * @param type one of the enumerated types above
+ * @return one of the enumerated permission actions above
+ */
+ PRUint32 testPermission(in nsIURI uri,
+ in PRUint32 type);
+
+ /**
+ * Allows enumeration of all stored permissions
+ * @return an nsISimpleEnumerator interface that allows access to
+ * nsIPermission objects
+ */
readonly attribute nsISimpleEnumerator enumerator;
- void remove(in AUTF8String host, in PRInt32 type);
};
%{ C++
-// {4F6B5E00-0C36-11d5-A535-0010A401EB10}
-#define NS_PERMISSIONMANAGER_CID \
-{ 0x4f6b5e00, 0xc36, 0x11d5, { 0xa5, 0x35, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 } }
#define NS_PERMISSIONMANAGER_CONTRACTID "@mozilla.org/permissionmanager;1"
+
+#define PERM_CHANGE_NOTIFICATION "perm-changed"
%}
diff --git a/extensions/cookie/nsImgManager.cpp b/extensions/cookie/nsImgManager.cpp
index 5f0e41d2e0dc..6b624e5fe6c2 100644
--- a/extensions/cookie/nsImgManager.cpp
+++ b/extensions/cookie/nsImgManager.cpp
@@ -1,4 +1,4 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -37,7 +37,6 @@
* ***** END LICENSE BLOCK ***** */
#include "nsImgManager.h"
-#include "nsImages.h"
#include "nsIDocument.h"
#include "nsIContent.h"
#include "nsCOMPtr.h"
@@ -48,122 +47,295 @@
#include "nsIScriptGlobalObject.h"
#include "nsIDOMWindow.h"
#include "nsIDocShellTreeItem.h"
+#include "nsCRT.h"
+#include "nsIPrefBranchInternal.h"
+#include "nsIObserverService.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
+// Possible behavior pref values
+#define IMAGE_ACCEPT 0
+#define IMAGE_NOFOREIGN 1
+#define IMAGE_DENY 2
-////////////////////////////////////////////////////////////////////////////////
+static const char kImageBehaviorPrefName[] = "network.image.imageBehavior";
+static const char kImageWarningPrefName[] = "network.image.warnAboutImages";
+static const char kImageBlockerPrefName[] = "imageblocker.enabled";
+static const char kImageBlockImageInMailNewsPrefName[] = "mailnews.message_display.disable_remote_image";
+static const PRInt32 kImageBehaviorPrefDefault = IMAGE_ACCEPT;
+static const PRBool kImageWarningPrefDefault = PR_FALSE;
+static const PRBool kImageBlockerPrefDefault = PR_FALSE;
+static const PRBool kImageBlockImageInMailNewsPrefDefault = PR_FALSE;
////////////////////////////////////////////////////////////////////////////////
// nsImgManager Implementation
+////////////////////////////////////////////////////////////////////////////////
-NS_IMPL_ISUPPORTS2(nsImgManager,
+NS_IMPL_ISUPPORTS4(nsImgManager,
nsIImgManager,
- nsIContentPolicy);
+ nsIContentPolicy,
+ nsIObserver,
+ nsSupportsWeakReference);
nsImgManager::nsImgManager()
{
}
-nsImgManager::~nsImgManager(void)
+nsImgManager::~nsImgManager()
{
}
nsresult nsImgManager::Init()
{
- IMAGE_RegisterPrefCallbacks();
- nsresult rv;
- mIOService = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
- return rv;
+ nsresult rv;
+
+ // On error, just don't use the host based lookup anymore. We can do the
+ // other things, like mailnews blocking
+ mPermissionManager = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
+
+ mPrefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
+
+ if (NS_SUCCEEDED(rv)) {
+ nsCOMPtr prefInternal = do_QueryInterface(mPrefBranch, &rv);
+ if (NS_SUCCEEDED(rv)) {
+ prefInternal->AddObserver(kImageBehaviorPrefName, this, PR_TRUE);
+
+ // We don't do anything with it yet, but let it be. (bug 110112, 146513)
+ prefInternal->AddObserver(kImageWarningPrefName, this, PR_TRUE);
+
+ // What is this pref, and how do you set it?
+ prefInternal->AddObserver(kImageBlockerPrefName, this, PR_TRUE);
+ prefInternal->AddObserver(kImageBlockImageInMailNewsPrefName, this, PR_TRUE);
+ }
+ }
+
+ rv = ReadPrefs();
+ NS_ASSERTION(NS_SUCCEEDED(rv), "Error occured reading image preferences");
+
+ return NS_OK;
}
-
-NS_IMETHODIMP nsImgManager::Block(nsIURI* imageURI)
-{
- ::IMAGE_Block(imageURI);
- return NS_OK;
-}
-
-
// nsIContentPolicy Implementation
NS_IMETHODIMP nsImgManager::ShouldLoad(PRInt32 aContentType,
nsIURI *aContentLoc,
nsISupports *aContext,
nsIDOMWindow *aWindow,
- PRBool *_retval)
+ PRBool *aShouldLoad)
{
- *_retval = PR_TRUE;
- nsresult rv = NS_OK;
+ *aShouldLoad = PR_TRUE;
+ nsresult rv = NS_OK;
- // we can't do anything w/ out these.
- if (!aContentLoc || !aContext) return rv;
+ // we can't do anything w/ out these.
+ if (!aContentLoc || !aContext) return rv;
- switch (aContentType) {
- case nsIContentPolicy::IMAGE:
- {
- // First, let be sure we are processing an HTTP or HTTPS images.
- // We should not waste time with chrome url...
- PRBool httpType;
- rv = aContentLoc->SchemeIs("http", &httpType);
- if (NS_FAILED(rv) || !httpType) {
- // check HTTPS as well
- rv = aContentLoc->SchemeIs("https", &httpType);
- if (NS_FAILED(rv) || !httpType) return rv;
- }
-
- nsCOMPtr baseURI;
- nsCOMPtr doc;
- nsCOMPtr content(do_QueryInterface(aContext));
- NS_ASSERTION(content, "no content avail");
- if (content) {
- rv = content->GetDocument(*getter_AddRefs(doc));
- if (NS_FAILED(rv) || !doc) return rv;
-
- rv = doc->GetBaseURL(*getter_AddRefs(baseURI));
- if (NS_FAILED(rv) || !baseURI) return rv;
-
- // Let check if we are running a mail window, doesn't matter if mail images are allowed
- if (IMAGE_BlockedInMail()) {
- nsCOMPtr docshell;
- rv = GetRootDocShell(aWindow, getter_AddRefs(docshell));
- if (docshell) {
- PRUint32 appType;
- rv = docshell->GetAppType(&appType);
- if (NS_SUCCEEDED(rv) && appType == nsIDocShell::APP_TYPE_MAIL) {
- //we are dealing with an mail or newsgroup window, let's block the image
- *_retval = PR_FALSE;
- return NS_OK;
- }
- }
- }
-
- nsCAutoString baseHost;
- rv = baseURI->GetAsciiHost(baseHost);
- if (NS_FAILED(rv)) return rv;
-
- nsCAutoString host;
- rv = aContentLoc->GetAsciiHost(host);
- if (NS_FAILED(rv)) return rv;
-
- return ::IMAGE_CheckForPermission(host.get(), baseHost.get(),
- _retval);
- }
- }
- break;
+ if (aContentType == nsIContentPolicy::IMAGE) {
+ // First, let be sure we are processing an HTTP or HTTPS images.
+ // We should not waste time with chrome url...
+ PRBool httpType;
+ rv = aContentLoc->SchemeIs("http", &httpType);
+ if (NS_FAILED(rv) || !httpType) {
+ // check HTTPS as well
+ rv = aContentLoc->SchemeIs("https", &httpType);
+ if (NS_FAILED(rv) || !httpType) return rv;
}
- return NS_OK;
+
+ nsCOMPtr baseURI;
+ nsCOMPtr doc;
+ nsCOMPtr content = do_QueryInterface(aContext);
+ NS_ASSERTION(content, "no content available");
+ if (content) {
+ rv = content->GetDocument(*getter_AddRefs(doc));
+ if (NS_FAILED(rv) || !doc) return rv;
+
+ rv = doc->GetBaseURL(*getter_AddRefs(baseURI));
+ if (NS_FAILED(rv) || !baseURI) return rv;
+
+ // Let check if we are running a mail window, doesn't matter if mail images are allowed
+ if (mBlockInMailNewsPref) {
+ nsCOMPtr docshell;
+ rv = GetRootDocShell(aWindow, getter_AddRefs(docshell));
+ if (docshell) {
+ PRUint32 appType;
+ rv = docshell->GetAppType(&appType);
+ if (NS_SUCCEEDED(rv) && appType == nsIDocShell::APP_TYPE_MAIL) {
+ //we are dealing with an mail or newsgroup window, let's block the image
+ *aShouldLoad = PR_FALSE;
+ return NS_OK;
+ }
+ }
+ }
+
+ rv = TestPermission(aContentLoc, baseURI, aShouldLoad);
+ if (NS_FAILED(rv)) return rv;
+ }
+ }
+ return NS_OK;
}
NS_IMETHODIMP nsImgManager::ShouldProcess(PRInt32 aContentType,
nsIURI *aDocumentLoc,
nsISupports *aContext,
nsIDOMWindow *aWindow,
- PRBool *_retval) {
+ PRBool *_retval)
+{
return NS_ERROR_NOT_IMPLEMENTED;
}
-NS_IMETHODIMP nsImgManager::GetRootDocShell(nsIDOMWindow *aWindow, nsIDocShell **result)
+NS_IMETHODIMP
+nsImgManager::TestPermission(nsIURI *aCurrentURI,
+ nsIURI *aFirstURI,
+ PRBool *aPermission)
+{
+ nsresult rv;
+ *aPermission = PR_TRUE;
+
+ // return if imageblocker is not enabled
+ // TODO: Why? Where is the pref set?
+ if (!mBlockerPref) {
+ *aPermission = (mBehaviorPref != IMAGE_DENY);
+ return NS_OK;
+ }
+
+ if (mBehaviorPref == IMAGE_DENY) {
+ *aPermission = PR_FALSE;
+ return NS_OK;
+ }
+
+ // Third party checking
+ if (mBehaviorPref == IMAGE_NOFOREIGN) {
+ // compare tails of names checking to see if they have a common domain
+ // we do this by comparing the tails of both names where each tail
+ // includes at least one dot
+
+ // A more generic method somewhere would be nice
+
+ nsCAutoString currentHost;
+ rv = aCurrentURI->GetAsciiHost(currentHost);
+ if (NS_FAILED(rv)) return rv;
+
+ // Search for two dots, starting at the end.
+ // If there are no two dots found, ++dot will turn to zero,
+ // that will return the entire string.
+ PRInt32 dot = currentHost.RFindChar('.');
+ dot = currentHost.RFindChar('.', dot-1);
+ ++dot;
+
+ // Get the domain, ie the last part of the host (www.domain.com -> domain.com)
+ // This will break on co.uk
+ const nsACString &tail = Substring(currentHost, dot, currentHost.Length() - dot);
+
+ nsCAutoString firstHost;
+ rv = aFirstURI->GetAsciiHost(firstHost);
+ if (NS_FAILED(rv)) return rv;
+
+ // Get the last part of the firstUri with the same length as |tail|
+ const nsACString &firstTail = Substring(firstHost, dot, firstHost.Length() - dot);
+
+ // Check that both tails are the same, and that just before the tail in
+ // |firstUri| there is a dot. That means both url are in the same domain
+ if ((dot > 0 && firstHost.CharAt(dot-1) != '.') || !tail.Equals(firstTail)) {
+ *aPermission = PR_FALSE;
+ return NS_OK;
+ }
+ }
+
+ if (mPermissionManager) {
+ PRUint32 temp;
+ mPermissionManager->TestPermission(aCurrentURI, nsIPermissionManager::IMAGE_TYPE, &temp);
+ // Blacklist for now
+ *aPermission = (temp != nsIPermissionManager::DENY_ACTION);
+ } else {
+ // no premission manager, return ok
+ *aPermission = PR_TRUE;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsImgManager::Observe(nsISupports *aSubject,
+ const char *aTopic,
+ const PRUnichar *aData)
+{
+ nsresult rv;
+
+ // check the topic, and the cached prefservice
+ if (!mPrefBranch) {
+ NS_ERROR("No prefbranch");
+ return NS_ERROR_FAILURE;
+ }
+
+ if (!nsCRT::strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
+ // which pref changed?
+ NS_ConvertUCS2toUTF8 pref(aData);
+
+ if (pref.Equals(kImageBehaviorPrefName)) {
+ rv = mPrefBranch->GetIntPref(kImageBehaviorPrefName, &mBehaviorPref);
+ if (NS_FAILED(rv) || mBehaviorPref < 0 || mBehaviorPref > 2) {
+ mBehaviorPref = kImageBehaviorPrefDefault;
+ }
+ } else if (pref.Equals(kImageWarningPrefName)) {
+ rv = mPrefBranch->GetIntPref(kImageWarningPrefName, &mWarningPref);
+ if (NS_FAILED(rv)) {
+ mWarningPref = kImageWarningPrefDefault;
+ }
+ } else if (pref.Equals(kImageBlockerPrefName)) {
+ rv = mPrefBranch->GetIntPref(kImageBlockerPrefName, &mBlockerPref);
+ if (NS_FAILED(rv)) {
+ mBlockerPref = kImageBlockerPrefDefault;
+ }
+ } else if (pref.Equals(kImageBlockImageInMailNewsPrefName)) {
+ rv = mPrefBranch->GetIntPref(kImageBlockImageInMailNewsPrefName, &mBlockInMailNewsPref);
+ if (NS_FAILED(rv)) {
+ mBlockInMailNewsPref = kImageBlockImageInMailNewsPrefDefault;
+ }
+ }
+ }
+
+ return NS_OK;
+}
+
+nsresult
+nsImgManager::ReadPrefs()
+{
+ nsresult rv, rv2 = NS_OK;
+
+ // check the prefservice is cached
+ if (!mPrefBranch) {
+ NS_ERROR("No prefbranch");
+ return NS_ERROR_FAILURE;
+ }
+
+ rv = mPrefBranch->GetIntPref(kImageBehaviorPrefName, &mBehaviorPref);
+ if (NS_FAILED(rv) || mBehaviorPref < 0 || mBehaviorPref > 2) {
+ rv2 = rv;
+ mBehaviorPref = kImageBehaviorPrefDefault;
+ }
+
+ rv = mPrefBranch->GetBoolPref(kImageBlockerPrefName, &mBlockerPref);
+ if (NS_FAILED(rv)) {
+ rv2 = rv;
+ mBlockerPref = kImageWarningPrefDefault;
+ }
+
+ rv = mPrefBranch->GetBoolPref(kImageWarningPrefName, &mWarningPref);
+ if (NS_FAILED(rv)) {
+ rv2 = rv;
+ mWarningPref = kImageBlockerPrefDefault;
+ }
+
+ rv = mPrefBranch->GetBoolPref(kImageBlockImageInMailNewsPrefName, &mBlockInMailNewsPref);
+ if (NS_FAILED(rv)) {
+ rv2 = rv;
+ mBlockInMailNewsPref = kImageBlockImageInMailNewsPrefDefault;
+ }
+
+ return rv2;
+}
+
+NS_IMETHODIMP
+nsImgManager::GetRootDocShell(nsIDOMWindow *aWindow, nsIDocShell **result)
{
nsresult rv;
diff --git a/extensions/cookie/nsImgManager.h b/extensions/cookie/nsImgManager.h
index 501d2d6d2554..f4ee210be911 100644
--- a/extensions/cookie/nsImgManager.h
+++ b/extensions/cookie/nsImgManager.h
@@ -44,11 +44,19 @@
#include "nsCOMPtr.h"
#include "nsIIOService.h"
#include "nsIDocShell.h"
+#include "nsIObserver.h"
+#include "nsWeakReference.h"
+#include "nsIPermissionManager.h"
+
+#include "nsIPrefService.h"
+#include "nsIPrefBranch.h"
////////////////////////////////////////////////////////////////////////////////
class nsImgManager : public nsIImgManager,
- public nsIContentPolicy
+ public nsIContentPolicy,
+ public nsIObserver,
+ public nsSupportsWeakReference
{
public:
@@ -56,17 +64,32 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIIMGMANAGER
NS_DECL_NSICONTENTPOLICY
+ NS_DECL_NSIOBSERVER
nsImgManager();
- virtual ~nsImgManager(void);
+ virtual ~nsImgManager();
nsresult Init();
+private:
+
+ nsresult ReadPrefs();
+
+ PRBool mBlockerPref;
+ PRInt32 mBehaviorPref;
+ PRBool mWarningPref;
+ PRBool mBlockInMailNewsPref;
+
+ PRBool mPolicy;
+
protected:
NS_IMETHOD GetRootDocShell(nsIDOMWindow *aWindow, nsIDocShell **result);
- // cached IOService
- nsCOMPtr mIOService;
-
+ nsCOMPtr mPermissionManager;
+ nsCOMPtr mPrefBranch;
};
+// {D60B3710-166D-11d5-A542-0010A401EB10}
+#define NS_IMGMANAGER_CID \
+{ 0xd60b3710, 0x166d, 0x11d5, { 0xa5, 0x42, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 } }
+
#endif /* nsImgManager_h__ */
diff --git a/extensions/cookie/nsModuleFactory.cpp b/extensions/cookie/nsModuleFactory.cpp
index 4d277638dcc3..b43b95b18f8f 100644
--- a/extensions/cookie/nsModuleFactory.cpp
+++ b/extensions/cookie/nsModuleFactory.cpp
@@ -53,6 +53,7 @@
#include "nsICategoryManager.h"
#include "nsXPIDLString.h"
#include "nsCookiePromptService.h"
+#include "nsCookiePermission.h"
// Define the constructor function for the objects
NS_GENERIC_FACTORY_CONSTRUCTOR(nsCookie)
@@ -64,6 +65,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPermissionManager, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPopupWindowManager, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCookieHTTPNotify, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsCookiePromptService)
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCookiePermission, Init)
static NS_METHOD
RegisterContentPolicy(nsIComponentManager *aCompMgr, nsIFile *aPath,
@@ -140,6 +142,11 @@ static const nsModuleComponentInfo components[] = {
NS_COOKIEPROMPTSERVICE_CONTRACTID,
nsCookiePromptServiceConstructor
},
+ { "CookiePermission",
+ NS_COOKIEPERMISSION_CID,
+ NS_COOKIEPERMISSION_CONTRACTID,
+ nsCookiePermissionConstructor
+ },
{ NS_COOKIEHTTPNOTIFY_CLASSNAME,
NS_COOKIEHTTPNOTIFY_CID,
NS_COOKIEHTTPNOTIFY_CONTRACTID,
diff --git a/extensions/cookie/nsPermission.cpp b/extensions/cookie/nsPermission.cpp
index 3ac84d56b8f9..64af9ec1ba7b 100644
--- a/extensions/cookie/nsPermission.cpp
+++ b/extensions/cookie/nsPermission.cpp
@@ -45,38 +45,33 @@
NS_IMPL_ISUPPORTS2(nsPermission, nsIPermission, nsISupportsWeakReference);
nsPermission::nsPermission()
- : permissionHost(0)
{
}
nsPermission::nsPermission
- (char * host,
- PRInt32 type,
- PRBool capability) {
- permissionHost = host;
- permissionType = type;
- permissionCapability = capability;
+ (const nsACString &aHost,
+ PRUint32 aType,
+ PRUint32 aCapability)
+: mHost(aHost),
+ mType(aType),
+ mCapability(aCapability)
+{
}
-nsPermission::~nsPermission(void) {
- if (permissionHost)
- PL_strfree(permissionHost);
+nsPermission::~nsPermission() {
}
-NS_IMETHODIMP nsPermission::GetHost(char * *aHost) {
- if (permissionHost) {
- *aHost = (char *) nsMemory::Clone(permissionHost, strlen(permissionHost) + 1);
- return NS_OK;
- }
- return NS_ERROR_NULL_POINTER;
-}
-
-NS_IMETHODIMP nsPermission::GetType(PRInt32 *aType) {
- *aType = permissionType;
+NS_IMETHODIMP nsPermission::GetHost(nsACString& aHost) {
+ aHost = mHost;
return NS_OK;
}
-NS_IMETHODIMP nsPermission::GetCapability(PRBool *aCapability) {
- *aCapability = permissionCapability;
+NS_IMETHODIMP nsPermission::GetType(PRUint32 *aType) {
+ *aType = mType;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPermission::GetCapability(PRUint32 *aCapability) {
+ *aCapability = mCapability;
return NS_OK;
}
diff --git a/extensions/cookie/nsPermission.h b/extensions/cookie/nsPermission.h
index 655f2a64e3fa..a2dcd579059e 100644
--- a/extensions/cookie/nsPermission.h
+++ b/extensions/cookie/nsPermission.h
@@ -41,27 +41,30 @@
#include "nsIPermission.h"
#include "nsWeakReference.h"
+#include "nsString.h"
////////////////////////////////////////////////////////////////////////////////
class nsPermission : public nsIPermission,
- public nsSupportsWeakReference {
+ public nsSupportsWeakReference
+{
public:
-
// nsISupports
NS_DECL_ISUPPORTS
NS_DECL_NSIPERMISSION
- // Note: following constructor takes ownership of the host string so the caller
- // of the constructor must not free them
- nsPermission(char * host, PRInt32 type, PRBool capability);
+ nsPermission(const nsACString &aHost, PRUint32 aType, PRUint32 aCapability);
nsPermission();
- virtual ~nsPermission(void);
+ virtual ~nsPermission();
protected:
- char * permissionHost;
- PRInt32 permissionType;
- PRBool permissionCapability;
+ nsCString mHost;
+ PRUint32 mType;
+ PRUint32 mCapability;
};
+// {28F16D80-157B-11d5-A542-0010A401EB10}
+#define NS_PERMISSION_CID \
+{ 0x28f16d80, 0x157b, 0x11d5, { 0xa5, 0x42, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 } }
+
#endif /* nsPermission_h__ */
diff --git a/extensions/cookie/nsPermissionManager.cpp b/extensions/cookie/nsPermissionManager.cpp
index 346c303ad698..e1b77682b317 100644
--- a/extensions/cookie/nsPermissionManager.cpp
+++ b/extensions/cookie/nsPermissionManager.cpp
@@ -38,70 +38,99 @@
#include "nsIServiceManager.h"
#include "nsPermissionManager.h"
+#include "nsPermission.h"
#include "nsCRT.h"
-#include "nsPermissions.h"
#include "nsIGenericFactory.h"
#include "nsXPIDLString.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDOMWindowInternal.h"
#include "nsIPrompt.h"
-#include "nsIObserverService.h"
-#include "nsPermission.h"
#include "nsNetUtil.h"
+#include "nsILineInputStream.h"
+#include "nsIPrefBranch.h"
+#include "nsIPrefBranchInternal.h"
+#include "nsIPrefService.h"
+#include "nsAppDirectoryServiceDefs.h"
+#include "prprf.h"
-static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
+static NS_NAMED_LITERAL_CSTRING(kPermissionsFileName, "cookperm.txt");
+static const char kPermissionChangeNotification[] = PERM_CHANGE_NOTIFICATION;
+
+typedef struct {
+ nsCString host;
+ nsVoidArray permissionList;
+} permission_HostStruct;
+
+typedef struct {
+ PRUint32 type;
+ PRUint32 permission;
+} permission_TypeStruct;
////////////////////////////////////////////////////////////////////////////////
class nsPermissionEnumerator : public nsISimpleEnumerator
{
- public:
+ public:
+ NS_DECL_ISUPPORTS
+
+ nsPermissionEnumerator(const nsVoidArray &aPermissionList)
+ : mHostCount(aPermissionList.Count()),
+ mHostIndex(0),
+ mTypeIndex(0),
+ mPermissionList(aPermissionList)
+ {
+ }
+
+ NS_IMETHOD GetNext(nsISupports **result);
- NS_DECL_ISUPPORTS
+ NS_IMETHOD HasMoreElements(PRBool *aResult)
+ {
+ *aResult = mHostCount > mHostIndex;
+ return NS_OK;
+ }
- nsPermissionEnumerator() : mHostCount(0), mTypeCount(0)
- {
- }
+ virtual ~nsPermissionEnumerator()
+ {
+ }
- NS_IMETHOD HasMoreElements(PRBool *result)
- {
- *result = PERMISSION_HostCount() > mHostCount;
- return NS_OK;
- }
-
- NS_IMETHOD GetNext(nsISupports **result)
- {
- char *host;
- PRBool capability;
- PRInt32 type;
- nsresult rv = PERMISSION_Enumerate
- (mHostCount, mTypeCount++, &host, &type, &capability);
- if (NS_SUCCEEDED(rv)) {
- if (mTypeCount == PERMISSION_TypeCount(mHostCount)) {
- mTypeCount = 0;
- mHostCount++;
- }
- nsIPermission *permission =
- new nsPermission(host, type, capability);
- *result = permission;
- NS_ADDREF(*result);
- } else {
- *result = nsnull;
- }
- return rv;
- }
-
- virtual ~nsPermissionEnumerator()
- {
- }
-
- protected:
- PRInt32 mHostCount;
- PRInt32 mTypeCount;
+ protected:
+ PRInt32 mHostCount;
+ PRInt32 mHostIndex;
+ PRInt32 mTypeIndex;
+ const nsVoidArray &mPermissionList;
};
NS_IMPL_ISUPPORTS1(nsPermissionEnumerator, nsISimpleEnumerator);
+NS_IMETHODIMP
+nsPermissionEnumerator::GetNext(nsISupports **aResult)
+{
+ if (mHostIndex >= mHostCount) {
+ *aResult = nsnull;
+ return NS_ERROR_FAILURE;
+ }
+
+ permission_HostStruct *hostStruct = NS_STATIC_CAST(permission_HostStruct*, mPermissionList.ElementAt(mHostIndex));
+ NS_ASSERTION(hostStruct, "corrupt permission list");
+
+ permission_TypeStruct *typeStruct = NS_STATIC_CAST(permission_TypeStruct*, hostStruct->permissionList.ElementAt(mTypeIndex++));
+ if (mTypeIndex == hostStruct->permissionList.Count()) {
+ mTypeIndex = 0;
+ mHostIndex++;
+ }
+
+ nsIPermission *permission =
+ new nsPermission(hostStruct->host, typeStruct->type, typeStruct->permission);
+ if (!permission) {
+ *aResult = nsnull;
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ *aResult = permission;
+ NS_ADDREF(permission);
+ return NS_OK;
+}
+
+
////////////////////////////////////////////////////////////////////////////////
// nsPermissionManager Implementation
@@ -111,65 +140,239 @@ nsPermissionManager::nsPermissionManager()
{
}
-nsPermissionManager::~nsPermissionManager(void)
+nsPermissionManager::~nsPermissionManager()
{
- PERMISSION_RemoveAll();
+ RemoveAllFromMemory();
}
nsresult nsPermissionManager::Init()
{
- PERMISSION_Read();
-
nsresult rv;
- nsCOMPtr observerService =
- do_GetService("@mozilla.org/observer-service;1", &rv);
- if (observerService) {
- observerService->AddObserver(this, "profile-before-change", PR_FALSE);
- observerService->AddObserver(this, "profile-do-change", PR_FALSE);
+
+ // Cache the permissions file
+ rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(mPermissionsFile));
+ if (NS_SUCCEEDED(rv)) {
+ rv = mPermissionsFile->AppendNative(kPermissionsFileName);
}
- mIOService = do_GetIOService();
- return rv;
-}
+ // Ignore an error. That is not a problem. No cookperm.txt usually.
+ Read();
+
+ mObserverService = do_GetService("@mozilla.org/observer-service;1", &rv);
+ if (NS_SUCCEEDED(rv)) {
+ mObserverService->AddObserver(this, "profile-before-change", PR_TRUE);
+ mObserverService->AddObserver(this, "profile-do-change", PR_TRUE);
+ }
-NS_IMETHODIMP nsPermissionManager::Add
- (const nsACString & objectURI, PRBool permission, PRInt32 type) {
- // XXX ideally we should change this interface to pass nsIURI
- nsCOMPtr uri;
- NS_NewURI(getter_AddRefs(uri), objectURI, nsnull, nsnull, mIOService);
- ::PERMISSION_Add(uri, permission, type);
return NS_OK;
}
-NS_IMETHODIMP nsPermissionManager::TestForBlocking
- (const nsACString &objectURI, PRInt32 type, PRBool* blocked) {
- // XXX ideally we should change this interface to pass nsIURI
- nsCOMPtr uri;
- NS_NewURI(getter_AddRefs(uri), objectURI, nsnull, nsnull, mIOService);
- ::PERMISSION_TestForBlocking(uri, blocked, type);
- return NS_OK;
-}
-
-NS_IMETHODIMP nsPermissionManager::RemoveAll(void) {
- ::PERMISSION_RemoveAll();
- ::PERMISSION_DeletePersistentUserData();
- return NS_OK;
-}
-
-NS_IMETHODIMP nsPermissionManager::GetEnumerator(nsISimpleEnumerator * *entries)
+NS_IMETHODIMP
+nsPermissionManager::Add(nsIURI *aURI,
+ PRUint32 aType,
+ PRUint32 aPermission)
{
- *entries = nsnull;
+ NS_ASSERTION(aURI, "could not get uri");
+ nsresult rv;
- nsPermissionEnumerator* permissionEnum = new nsPermissionEnumerator();
- if (permissionEnum == nsnull)
- return NS_ERROR_OUT_OF_MEMORY;
- NS_ADDREF(permissionEnum);
- *entries = permissionEnum;
+ nsCAutoString hostPort;
+ aURI->GetHostPort(hostPort);
+ if (hostPort.IsEmpty()) {
+ // Nothing to add
return NS_OK;
+ }
+
+ rv = AddInternal(hostPort, aType, aPermission);
+ if (NS_FAILED(rv)) return rv;
+
+ // Notify permission manager dialog to update its display
+ //
+ // This used to be conditional, but now we use AddInternal
+ // for cases when no notification is needed
+ NotifyObservers(hostPort);
+
+ mChangedList = PR_TRUE;
+ return Write();
}
-NS_IMETHODIMP nsPermissionManager::Remove(const nsACString & host, PRInt32 type) {
- ::PERMISSION_Remove(host, type);
+//Only add to memory, don't save. That's up to the caller.
+nsresult
+nsPermissionManager::AddInternal(const nsACString &aHost,
+ PRUint32 aType,
+ PRUint32 aPermission)
+{
+ // find existing entry for host
+ permission_HostStruct *hostStruct;
+ PRBool hostFound = PR_FALSE;
+ PRInt32 hostCount = mPermissionList.Count();
+ PRInt32 hostIndex;
+ for (hostIndex = 0; hostIndex < hostCount; ++hostIndex) {
+ hostStruct = NS_STATIC_CAST(permission_HostStruct*, mPermissionList.ElementAt(hostIndex));
+ NS_ASSERTION(hostStruct, "corrupt permission list");
+ if (aHost.Equals(hostStruct->host)) {
+ // host found in list
+ hostFound = PR_TRUE;
+ break;
+ } else if (aHost < hostStruct->host) {
+ // Need to insert new entry here for alphabetized list
+ break;
+ }
+ }
+
+ if (!hostFound) {
+ // create a host structure for the host
+ hostStruct = new permission_HostStruct;
+ if (!hostStruct) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ hostStruct->host = aHost;
+
+ // Insert host structure into the list
+ if (hostIndex < hostCount) {
+ mPermissionList.InsertElementAt(hostStruct, hostIndex);
+ } else {
+ mPermissionList.AppendElement(hostStruct);
+ }
+ }
+
+ // See if host already has an entry for this type
+ permission_TypeStruct *typeStruct;
+ PRInt32 typeCount = hostStruct->permissionList.Count();
+ for (PRInt32 typeIndex=0; typeIndex < typeCount; ++typeIndex) {
+ typeStruct = NS_STATIC_CAST(permission_TypeStruct*, hostStruct->permissionList.ElementAt(typeIndex));
+ NS_ASSERTION(typeStruct, "corrupt permission list");
+ if (typeStruct->type == aType) {
+ // Type found. Modify the corresponding permission
+ typeStruct->permission = aPermission;
+ return NS_OK;
+ }
+ }
+
+ // Create a type structure and attach it to the host structure
+ typeStruct = new permission_TypeStruct;
+ typeStruct->type = aType;
+ typeStruct->permission = aPermission;
+ hostStruct->permissionList.AppendElement(typeStruct);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPermissionManager::Remove(const nsACString &aHost,
+ PRUint32 aType)
+{
+ nsresult rv;
+
+ // Find existing entry for host
+ permission_HostStruct *hostStruct;
+
+ PRInt32 hostCount = mPermissionList.Count();
+ for (PRInt32 hostIndex = 0; hostIndex < hostCount; ++hostIndex) {
+ hostStruct = NS_STATIC_CAST(permission_HostStruct*, mPermissionList.ElementAt(hostIndex));
+ NS_ASSERTION(hostStruct, "corrupt permission list");
+
+ if (aHost.Equals(hostStruct->host)) {
+ // Host found in list, see if it has an entry for this type
+ permission_TypeStruct *typeStruct;
+
+ PRInt32 typeCount = hostStruct->permissionList.Count();
+ for (PRInt32 typeIndex = 0; typeIndex < typeCount; ++typeIndex) {
+ typeStruct = NS_STATIC_CAST(permission_TypeStruct*, hostStruct->permissionList.ElementAt(typeIndex));
+ NS_ASSERTION(typeStruct, "corrupt permission list");
+ if (typeStruct->type == aType) {
+ delete typeStruct;
+ hostStruct->permissionList.RemoveElementAt(typeIndex);
+ --typeCount;
+
+ // If no more types are present, remove the entry
+ if (typeCount == 0) {
+ mPermissionList.RemoveElementAt(hostIndex);
+ delete hostStruct;
+ }
+ mChangedList = PR_TRUE;
+ Write();
+
+ // Notify Observers
+ NotifyObservers(aHost);
+
+ return NS_OK;
+ }
+ }
+
+ break;
+ }
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPermissionManager::RemoveAll()
+{
+ RemoveAllFromMemory();
+ Write();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPermissionManager::TestPermission(nsIURI *aURI,
+ PRUint32 aType,
+ PRUint32 *aPermission)
+{
+ NS_ASSERTION(aURI, "could not get uri");
+ NS_ASSERTION(aPermission, "no permission pointer");
+
+ // set the default
+ *aPermission = nsIPermissionManager::UNKNOWN_ACTION;
+
+ nsCAutoString hostPort;
+ aURI->GetHostPort(hostPort);
+ // Don't error on no host. Just return UNKNOWN_ACTION as permission.
+ if (hostPort.IsEmpty()) {
+ return NS_OK;
+ }
+
+ permission_HostStruct *hostStruct;
+ permission_TypeStruct *typeStruct;
+
+ //TODO: Look for the specific host, if not found check its domains
+ // Do we want that? Currenty, it is not actually done
+
+ // find host name within list
+ PRInt32 hostCount = mPermissionList.Count();
+ for (PRInt32 i = 0; i < hostCount; ++i) {
+ hostStruct = NS_STATIC_CAST(permission_HostStruct*, mPermissionList.ElementAt(i));
+ NS_ASSERTION(hostStruct, "corrupt permission list");
+
+ if (hostStruct->host.Equals(hostPort)) {
+ // search for type in the permission list for this host
+ PRInt32 typeCount = hostStruct->permissionList.Count();
+ for (PRInt32 typeIndex = 0; typeIndex < typeCount; ++typeIndex) {
+ typeStruct = NS_STATIC_CAST(permission_TypeStruct*, hostStruct->permissionList.ElementAt(typeIndex));
+ NS_ASSERTION(typeStruct, "corrupt permission list");
+
+ if (typeStruct->type == aType) {
+ // type found. Obtain the corresponding permission
+ *aPermission = typeStruct->permission;
+ return NS_OK;
+ }
+ }
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPermissionManager::GetEnumerator(nsISimpleEnumerator **aEnum)
+{
+
+ nsPermissionEnumerator* permissionEnum = new nsPermissionEnumerator(mPermissionList);
+ if (!permissionEnum) {
+ *aEnum = nsnull;
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ NS_ADDREF(permissionEnum);
+ *aEnum = permissionEnum;
return NS_OK;
}
@@ -188,15 +391,228 @@ NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const char *aT
// was accepted). If this condition ever changes, the permission
// file would need to be updated here.
- PERMISSION_RemoveAll();
+ RemoveAllFromMemory();
if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("shutdown-cleanse").get()))
- PERMISSION_DeletePersistentUserData();
+ if (mPermissionsFile) {
+ mPermissionsFile->Remove(PR_FALSE);
+ }
}
else if (!nsCRT::strcmp(aTopic, "profile-do-change")) {
// The profile has aleady changed.
// Now just read them from the new profile location.
- PERMISSION_Read();
+
+ // Re-get the permissions file
+ rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(mPermissionsFile));
+ if (NS_SUCCEEDED(rv)) {
+ rv = mPermissionsFile->AppendNative(kPermissionsFileName);
+ }
+ Read();
}
return rv;
}
+
+//*****************************************************************************
+//*** nsPermissionManager private methods
+//*****************************************************************************
+
+nsresult
+nsPermissionManager::RemoveAllFromMemory()
+{
+ permission_HostStruct *hostStruct;
+ permission_TypeStruct *typeStruct;
+
+ PRInt32 hostCount = mPermissionList.Count();
+ for (PRInt32 hostIndex = hostCount-1; hostIndex >= 0; --hostIndex) {
+ hostStruct = NS_STATIC_CAST(permission_HostStruct*, mPermissionList.ElementAt(hostIndex));
+ NS_ASSERTION(hostStruct, "corrupt permission list");
+
+ PRInt32 typeCount = hostStruct->permissionList.Count();
+ for (PRInt32 typeIndex = typeCount-1; typeIndex >= 0; --typeIndex) {
+ typeStruct = NS_STATIC_CAST(permission_TypeStruct*, hostStruct->permissionList.ElementAt(typeIndex));
+ delete typeStruct;
+ hostStruct->permissionList.RemoveElementAt(typeIndex);
+ }
+ // no more types are present, remove the entry
+ mPermissionList.RemoveElementAt(hostIndex);
+ delete hostStruct;
+ }
+
+ return NS_OK;
+}
+
+// broadcast a notification that a permission pref has changed
+nsresult
+nsPermissionManager::NotifyObservers(const nsACString &aHost)
+{
+ if (mObserverService) {
+ return mObserverService->NotifyObservers(NS_STATIC_CAST(nsIPermissionManager *, this),
+ kPermissionChangeNotification,
+ NS_ConvertUTF8toUCS2(aHost).get());
+ }
+ return NS_ERROR_FAILURE;
+}
+
+// Note:
+// We don't do checkbox states here anymore.
+// When a consumer wants it back, that is up to the consumer, not this backend
+// For cookies, it is now done with a persist in the dialog xul file.
+
+nsresult
+nsPermissionManager::Read()
+{
+ nsresult rv;
+
+ if (!mPermissionsFile) {
+ return NS_ERROR_FAILURE;
+ }
+
+ nsCOMPtr fileInputStream;
+ rv = NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), mPermissionsFile);
+ if (NS_FAILED(rv)) return rv;
+
+ nsCOMPtr lineInputStream = do_QueryInterface(fileInputStream, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ /* format is:
+ * host \t number permission \t number permission ... \n
+ * if this format isn't respected we move onto the next line in the file.
+ */
+
+ nsAutoString bufferUnicode;
+ nsCAutoString buffer;
+ PRBool isMore = PR_TRUE;
+ while (isMore && NS_SUCCEEDED(lineInputStream->ReadLine(bufferUnicode, &isMore))) {
+ CopyUCS2toASCII(bufferUnicode, buffer);
+ if (buffer.IsEmpty() || buffer.First() == '#') {
+ continue;
+ }
+
+ PRInt32 hostIndex, permissionIndex;
+ PRUint32 nextPermissionIndex = 0;
+ hostIndex = 0;
+
+ if ((permissionIndex = buffer.FindChar('\t', hostIndex) + 1) == 0) {
+ continue;
+ }
+
+ // ignore leading periods in host name
+ while (hostIndex < permissionIndex && (buffer.CharAt(hostIndex) == '.')) {
+ ++hostIndex;
+ }
+
+ nsDependentCSubstring host(buffer, hostIndex, permissionIndex - hostIndex - 1);
+
+ for (;;) {
+ if (nextPermissionIndex == buffer.Length()+1) {
+ break;
+ }
+ if ((nextPermissionIndex = buffer.FindChar('\t', permissionIndex)+1) == 0) {
+ nextPermissionIndex = buffer.Length()+1;
+ }
+ const nsASingleFragmentCString &permissionString = Substring(buffer, permissionIndex, nextPermissionIndex - permissionIndex - 1);
+ permissionIndex = nextPermissionIndex;
+
+ PRUint32 type = 0;
+ PRUint32 index = 0;
+
+ if (permissionString.IsEmpty()) {
+ continue; // empty permission entry -- should never happen
+ }
+ // Parse "2T"
+ char c = permissionString.CharAt(index);
+ while (index < permissionString.Length() && c >= '0' && c <= '9') {
+ type = 10*type + (c-'0');
+ c = permissionString.CharAt(++index);
+ }
+ if (index >= permissionString.Length()) {
+ continue; // bad format for this permission entry
+ }
+ PRUint32 permission = (permissionString.CharAt(index) == 'T') ? nsIPermissionManager::ALLOW_ACTION : nsIPermissionManager::DENY_ACTION;
+
+ // Ignore @@@ as host. Old style checkbox status
+ if (!permissionString.IsEmpty() && !host.Equals(NS_LITERAL_CSTRING("@@@@"))) {
+ rv = AddInternal(host, type, permission);
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ }
+ }
+
+ mChangedList = PR_FALSE;
+
+ return NS_OK;
+}
+
+nsresult
+nsPermissionManager::Write()
+{
+ nsresult rv;
+
+ if (!mChangedList) {
+ return NS_OK;
+ }
+
+ if (!mPermissionsFile) {
+ return NS_ERROR_FAILURE;
+ }
+
+ nsCOMPtr fileOutputStream;
+ rv = NS_NewLocalFileOutputStream(getter_AddRefs(fileOutputStream), mPermissionsFile);
+ if (NS_FAILED(rv)) return rv;
+
+ // get a buffered output stream 4096 bytes big, to optimize writes
+ nsCOMPtr bufferedOutputStream;
+ rv = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream), fileOutputStream, 4096);
+ if (NS_FAILED(rv)) return rv;
+
+ permission_HostStruct *hostStruct;
+ permission_TypeStruct *typeStruct;
+
+ static const char kHeader[] =
+ "# HTTP Permission File\n"
+ "# http://www.netscape.com/newsref/std/cookie_spec.html\n"
+ "# This is a generated file! Do not edit.\n\n";
+
+ bufferedOutputStream->Write(kHeader, sizeof(kHeader) - 1, &rv);
+
+ /* format shall be:
+ * host \t permission \t permission ... \n
+ */
+ static const char kTab[] = "\t";
+ static const char kNew[] = "\n";
+ static const char kTrue[] = "F";
+ static const char kFalse[] = "T";
+
+ PRInt32 hostCount = mPermissionList.Count();
+ for (PRInt32 i = 0; i < hostCount; ++i) {
+ hostStruct = NS_STATIC_CAST(permission_HostStruct*, mPermissionList.ElementAt(i));
+ NS_ASSERTION(hostStruct, "corrupt permission list");
+
+ bufferedOutputStream->Write(hostStruct->host.get(), hostStruct->host.Length(), &rv);
+
+ PRUint32 typeCount = hostStruct->permissionList.Count();
+ for (PRUint32 typeIndex = 0; typeIndex < typeCount; ++typeIndex) {
+ typeStruct = NS_STATIC_CAST(permission_TypeStruct*, hostStruct->permissionList.ElementAt(typeIndex));
+ NS_ASSERTION(typeStruct, "corrupt permission list");
+
+ bufferedOutputStream->Write(kTab, sizeof(kTab) - 1, &rv);
+
+ char typeString[5];
+ PRUint32 len = PR_snprintf(typeString, sizeof(typeString), "%u", typeStruct->type);
+ bufferedOutputStream->Write(typeString, len, &rv);
+
+ if (typeStruct->permission == nsIPermissionManager::ALLOW_ACTION) {
+ bufferedOutputStream->Write(kTrue, sizeof(kTrue) - 1, &rv);
+ } else if (typeStruct->permission == nsIPermissionManager::DENY_ACTION) {
+ bufferedOutputStream->Write(kFalse, sizeof(kFalse) - 1, &rv);
+ }
+ }
+ bufferedOutputStream->Write(kNew, sizeof(kNew) - 1, &rv);
+ }
+
+ mChangedList = PR_FALSE;
+
+ return NS_OK;
+}
+
diff --git a/extensions/cookie/nsPermissionManager.h b/extensions/cookie/nsPermissionManager.h
index ba5a0d73fd73..222dfb1658ee 100644
--- a/extensions/cookie/nsPermissionManager.h
+++ b/extensions/cookie/nsPermissionManager.h
@@ -41,15 +41,19 @@
#include "nsIPermissionManager.h"
#include "nsIObserver.h"
+#include "nsIObserverService.h"
#include "nsWeakReference.h"
#include "nsCOMPtr.h"
#include "nsIIOService.h"
+#include "nsVoidArray.h"
+#include "nsIFile.h"
////////////////////////////////////////////////////////////////////////////////
class nsPermissionManager : public nsIPermissionManager,
public nsIObserver,
- public nsSupportsWeakReference {
+ public nsSupportsWeakReference
+{
public:
// nsISupports
@@ -58,13 +62,29 @@ public:
NS_DECL_NSIOBSERVER
nsPermissionManager();
- virtual ~nsPermissionManager(void);
+ virtual ~nsPermissionManager();
nsresult Init();
-protected:
- // cached IOService
- nsCOMPtr mIOService;
-
+private:
+
+ nsresult AddInternal(const nsACString &aHost,
+ PRUint32 aType,
+ PRUint32 aPermission);
+
+ nsresult Read();
+ nsresult Write();
+ nsresult NotifyObservers(const nsACString &aHost);
+ nsresult RemoveAllFromMemory();
+
+ nsCOMPtr mObserverService;
+ nsCOMPtr mPermissionsFile;
+ nsVoidArray mPermissionList;
+ PRBool mChangedList;
+
};
+// {4F6B5E00-0C36-11d5-A535-0010A401EB10}
+#define NS_PERMISSIONMANAGER_CID \
+{ 0x4f6b5e00, 0xc36, 0x11d5, { 0xa5, 0x35, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 } }
+
#endif /* nsPermissionManager_h__ */
diff --git a/extensions/cookie/nsPopupWindowManager.cpp b/extensions/cookie/nsPopupWindowManager.cpp
index 4ee4066cda51..3c1fe028f998 100644
--- a/extensions/cookie/nsPopupWindowManager.cpp
+++ b/extensions/cookie/nsPopupWindowManager.cpp
@@ -39,8 +39,8 @@
#include "nsCOMPtr.h"
#include "nsCRT.h"
-#include "nsPermissions.h"
#include "nsPermission.h"
+#include "nsIPermissionManager.h"
#include "nsIObserverService.h"
#include "nsIPrefBranch.h"
@@ -49,69 +49,11 @@
#include "nsIServiceManagerUtils.h"
#include "nsIURI.h"
-/*
- The Popup Window Manager maintains popup window permissions by website.
+/**
+ * The Popup Window Manager maintains popup window permissions by website.
*/
-#define POPUP_PREF "dom.disable_open_during_load"
-static const char sPopupDisablePref[] = POPUP_PREF;
-static const char sPermissionChangeNotification[] = PPM_CHANGE_NOTIFICATION;
-static const char sXPCOMShutdownTopic[] = NS_XPCOM_SHUTDOWN_OBSERVER_ID;
-static const char sPrefChangedTopic[] = NS_PREFBRANCH_PREFCHANGE_TOPIC_ID;
-
-class nsPopupEnumerator : public nsISimpleEnumerator
-{
- public:
-
- NS_DECL_ISUPPORTS
-
- nsPopupEnumerator() : mHostCurrent(0), mTypeCurrent(0), mHostsFound(0)
- {
- mHostCount = PERMISSION_HostCountForType(WINDOWPERMISSION);
- }
-
- NS_IMETHOD HasMoreElements(PRBool *result)
- {
- *result = mHostCount > mHostsFound;
- return NS_OK;
- }
-
- NS_IMETHOD GetNext(nsISupports **result)
- {
- char *host;
- PRBool capability;
- PRInt32 type;
-
- *result = nsnull;
-
- while (NS_SUCCEEDED(PERMISSION_Enumerate(mHostCurrent, mTypeCurrent++, &host, &type, &capability))) {
- if ((mTypeCurrent == PERMISSION_TypeCount(mHostCurrent)) || (type == WINDOWPERMISSION)) {
- mTypeCurrent = 0;
- mHostCurrent++;
- }
- if (type == WINDOWPERMISSION) {
- nsIPermission *permission = new nsPermission(host, type, capability);
- *result = permission;
- NS_ADDREF(*result);
- mHostsFound++;
- break;
- }
- }
- return NS_OK;
- }
-
- virtual ~nsPopupEnumerator()
- {
- }
-
- protected:
- PRInt32 mHostCurrent;
- PRInt32 mTypeCurrent;
- PRInt32 mHostCount;
- PRInt32 mHostsFound;
-};
-
-NS_IMPL_ISUPPORTS1(nsPopupEnumerator, nsISimpleEnumerator);
+static const char kPopupDisablePref[] = "dom.disable_open_during_load";
//*****************************************************************************
//*** nsPopupWindowManager object management and nsISupports
@@ -124,31 +66,35 @@ nsPopupWindowManager::nsPopupWindowManager() :
nsPopupWindowManager::~nsPopupWindowManager(void)
{
- StopObservingThings();
}
-NS_IMPL_ISUPPORTS2(nsPopupWindowManager,
+NS_IMPL_ISUPPORTS3(nsPopupWindowManager,
nsIPopupWindowManager,
- nsIObserver);
+ nsIObserver,
+ nsSupportsWeakReference);
nsresult
nsPopupWindowManager::Init()
{
- mOS = do_GetService("@mozilla.org/observer-service;1");
- // we bypass the permission manager API's but it still owns the underlying
- // list--we need to let it do the initializing to avoid conflict.
- mPermManager = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
- nsCOMPtr prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
- if (prefs)
- prefs->GetBranch("", getter_AddRefs(mPopupPrefBranch));
+ nsresult rv;
+ mPermissionManager = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
- if (mOS && mPermManager && mPopupPrefBranch) {
- // initialize our local copy of the pref
- Observe(NS_STATIC_CAST(nsIPopupWindowManager *, this),
- sPrefChangedTopic, NS_LITERAL_STRING(POPUP_PREF).get());
- return ObserveThings();
- }
- return NS_ERROR_FAILURE;
+ mPrefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
+ if (NS_SUCCEEDED(rv)) {
+ PRBool permission;
+ rv = mPrefBranch->GetBoolPref(kPopupDisablePref, &permission);
+ if (NS_FAILED(rv)) {
+ permission = PR_FALSE;
+ }
+ mPolicy = permission ? DENY_POPUP : ALLOW_POPUP;
+
+ nsCOMPtr prefInternal = do_QueryInterface(mPrefBranch, &rv);
+ if (NS_SUCCEEDED(rv)) {
+ prefInternal->AddObserver(kPopupDisablePref, this, PR_TRUE);
+ }
+ }
+
+ return NS_OK;
}
//*****************************************************************************
@@ -166,210 +112,56 @@ nsPopupWindowManager::GetDefaultPermission(PRUint32 *aDefaultPermission)
NS_IMETHODIMP
nsPopupWindowManager::SetDefaultPermission(PRUint32 aDefaultPermission)
{
- mPolicy = (aDefaultPermission == DENY_POPUP) ? DENY_POPUP : ALLOW_POPUP;
+ mPolicy = aDefaultPermission;
return NS_OK;
}
+
NS_IMETHODIMP
-nsPopupWindowManager::Add(nsIURI *aURI, PRBool aPermit)
+nsPopupWindowManager::TestPermission(nsIURI *aURI, PRUint32 *aPermission)
{
NS_ENSURE_ARG_POINTER(aURI);
- if (!mPermManager)
- // if we couldn't initialize the permission manager Permission_AddHost()
- // will create a new list that could stomp an existing cookperm.txt
- return NS_ERROR_FAILURE;
-
- nsCAutoString uri;
- aURI->GetHostPort(uri);
- if (uri.IsEmpty())
- return NS_ERROR_FAILURE;
-
- if (NS_SUCCEEDED(Permission_AddHost(uri, aPermit, WINDOWPERMISSION, PR_TRUE)))
- return NotifyObservers(aURI);
-
- return NS_ERROR_FAILURE;
-}
+ NS_ENSURE_ARG_POINTER(aPermission);
-NS_IMETHODIMP
-nsPopupWindowManager::Remove(nsIURI *aURI)
-{
- NS_ENSURE_ARG_POINTER(aURI);
-
- nsCAutoString uri;
- aURI->GetHostPort(uri);
- if (uri.IsEmpty())
- return NS_ERROR_FAILURE;
-
- PERMISSION_Remove(uri, WINDOWPERMISSION);
- return NotifyObservers(aURI);
-}
-
-NS_IMETHODIMP
-nsPopupWindowManager::RemoveAll()
-{
- return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-/* The underlying manager, nsPermissionManager, won't store permissions
- for an url lacking a host. It's good to know these things up front.
-*/
-NS_IMETHODIMP
-nsPopupWindowManager::TestSuitability(nsIURI *aURI, PRBool *_retval)
-{
- NS_ENSURE_ARG_POINTER(aURI);
- NS_ENSURE_ARG_POINTER(_retval);
-
- nsCAutoString hostPort;
- aURI->GetHostPort(hostPort);
- *_retval = hostPort.IsEmpty() ? PR_FALSE : PR_TRUE;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPopupWindowManager::TestPermission(nsIURI *aURI, PRUint32 *_retval)
-{
- NS_ENSURE_ARG_POINTER(aURI);
- NS_ENSURE_ARG_POINTER(_retval);
-
- *_retval = mPolicy;
-
- nsCAutoString uri;
- aURI->GetHostPort(uri);
- if (uri.IsEmpty())
- return NS_OK;
-
- /* Look for the specific host, if not found check its domains */
nsresult rv;
- PRBool permission;
- PRInt32 offset = 0;
- const char* host = uri.get();
- do {
- rv = permission_CheckFromList(host+offset, permission, WINDOWPERMISSION);
- if (NS_SUCCEEDED(rv)) {
- /* found a value for the host/domain */
- *_retval = permission ? ALLOW_POPUP : DENY_POPUP;
- break;
+ PRUint32 permit;
+
+ if (mPermissionManager) {
+ rv = mPermissionManager->TestPermission(aURI,
+ nsIPermissionManager::POPUP_TYPE,
+ &permit);
+
+ // Share some constants between interfaces?
+ if (permit == nsIPermissionManager::ALLOW_ACTION) {
+ *aPermission = ALLOW_POPUP;
+ } else if (permit == nsIPermissionManager::DENY_ACTION) {
+ *aPermission = DENY_POPUP;
+ } else {
+ *aPermission = mPolicy;
}
-
- /* try the parent domain */
- offset = uri.FindChar('.', offset) + 1;
- } while (offset > 0 );
-
+ } else {
+ *aPermission = mPolicy;
+ }
return NS_OK;
}
-NS_IMETHODIMP
-nsPopupWindowManager::GetEnumerator(nsISimpleEnumerator **_retval)
-{
- *_retval = nsnull;
-
- nsPopupEnumerator* popupEnum = new nsPopupEnumerator();
- if (popupEnum == nsnull)
- return NS_ERROR_OUT_OF_MEMORY;
-
- NS_ADDREF(popupEnum);
- *_retval = popupEnum;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPopupWindowManager::AddObserver(nsIObserver *aObserver)
-{
- if (mOS)
- return mOS->AddObserver(aObserver, sPermissionChangeNotification, PR_FALSE);
- return NS_ERROR_FAILURE;
-}
-
-NS_IMETHODIMP
-nsPopupWindowManager::RemoveObserver(nsIObserver *aObserver)
-{
- if (mOS)
- return mOS->RemoveObserver(aObserver, sPermissionChangeNotification);
- return NS_ERROR_FAILURE;
-}
-
//*****************************************************************************
//*** nsPopupWindowManager::nsIObserver
//*****************************************************************************
NS_IMETHODIMP
-nsPopupWindowManager::Observe(nsISupports *aSubject, const char *aTopic,
+nsPopupWindowManager::Observe(nsISupports *aSubject,
+ const char *aTopic,
const PRUnichar *aData)
{
- if (nsCRT::strcmp(aTopic, sPrefChangedTopic) == 0 &&
- NS_LITERAL_STRING(POPUP_PREF).Equals(aData)) {
+ NS_ConvertUCS2toUTF8 pref(aData);
+ if (pref.Equals(kPopupDisablePref)) {
// refresh our local copy of the "disable popups" pref
PRBool permission = PR_FALSE;
- if (mPopupPrefBranch) {
- mPopupPrefBranch->GetBoolPref(sPopupDisablePref, &permission);
+ if (mPrefBranch) {
+ mPrefBranch->GetBoolPref(kPopupDisablePref, &permission);
}
mPolicy = permission ? DENY_POPUP : ALLOW_POPUP;
- } else if (nsCRT::strcmp(aTopic, sXPCOMShutdownTopic) == 0) {
- // unhook cyclical references
- StopObservingThings();
- DeInitialize();
}
return NS_OK;
}
-
-//*****************************************************************************
-//*** nsPopupWindowManager private methods
-//*****************************************************************************
-
-/* Register for notifications of interest. That's a change in the pref
- we're watching and XPCOM shutdown. */
-nsresult
-nsPopupWindowManager::ObserveThings()
-{
- nsresult rv = NS_ERROR_FAILURE;
-
- if (mOS)
- rv = mOS->AddObserver(this, sXPCOMShutdownTopic, PR_FALSE);
-
- if (NS_SUCCEEDED(rv)) {
- nsCOMPtr ibranch(do_QueryInterface(mPopupPrefBranch));
- if (ibranch) {
- ibranch->AddObserver(sPopupDisablePref, this, PR_FALSE);
- }
- }
-
- return rv;
-}
-
-// undo ObserveThings
-nsresult
-nsPopupWindowManager::StopObservingThings()
-{
- nsCOMPtr ibranch(do_QueryInterface(mPopupPrefBranch));
- if (ibranch) {
- ibranch->RemoveObserver(sPopupDisablePref, this);
- }
-
- if (mOS)
- mOS->RemoveObserver(this, sXPCOMShutdownTopic);
-
- return NS_OK;
-}
-
-// broadcast a notification that a popup pref has changed
-nsresult
-nsPopupWindowManager::NotifyObservers(nsIURI *aURI)
-{
- if (mOS) {
- nsCAutoString uri;
- aURI->GetSpec(uri);
- return mOS->NotifyObservers(NS_STATIC_CAST(nsIPopupWindowManager *, this),
- sPermissionChangeNotification, NS_ConvertUTF8toUCS2(uri).get());
- }
- return NS_ERROR_FAILURE;
-}
-
-// unhook cyclical references so we can be properly shut down
-void
-nsPopupWindowManager::DeInitialize()
-{
- mOS = 0;
- mPermManager = 0;
- mPopupPrefBranch = 0;
-}
-
diff --git a/extensions/cookie/nsPopupWindowManager.h b/extensions/cookie/nsPopupWindowManager.h
index 9c05444abc24..2098ea2cb158 100644
--- a/extensions/cookie/nsPopupWindowManager.h
+++ b/extensions/cookie/nsPopupWindowManager.h
@@ -45,11 +45,13 @@
#include "nsIPermissionManager.h"
#include "nsIPopupWindowManager.h"
#include "nsIPrefBranch.h"
+#include "nsWeakReference.h"
class nsIURI;
class nsPopupWindowManager : public nsIPopupWindowManager,
- public nsIObserver {
+ public nsIObserver,
+ public nsSupportsWeakReference {
public:
NS_DECL_ISUPPORTS
@@ -61,15 +63,9 @@ public:
nsresult Init();
private:
- nsresult ObserveThings();
- nsresult StopObservingThings();
- nsresult NotifyObservers(nsIURI *aURI);
- void DeInitialize();
-
PRUint32 mPolicy;
- nsCOMPtr mOS;
- nsCOMPtr mPermManager;
- nsCOMPtr mPopupPrefBranch;
+ nsCOMPtr mPermissionManager;
+ nsCOMPtr mPrefBranch;
};
// {4275d3f4-752a-427a-b432-14d5dda1c20b}
diff --git a/extensions/cookie/resources/content/cookieAcceptDialog.js b/extensions/cookie/resources/content/cookieAcceptDialog.js
index 8963a694cf19..565b296d654e 100644
--- a/extensions/cookie/resources/content/cookieAcceptDialog.js
+++ b/extensions/cookie/resources/content/cookieAcceptDialog.js
@@ -126,7 +126,8 @@ function onload()
messageParent.appendChild(descriptionNode);
}
- document.getElementById('persistDomainAcceptance').checked = params.GetInt(nsICookieAcceptDialog.REMEMBER_DECISION) > 0;
+ // Must we remember the decision?
+ params.SetInt(nsICookieAcceptDialog.REMEMBER_DECISION, document.getElementById('persistDomainAcceptance').checked);
if (cookie) {
document.getElementById('ifl_name').setAttribute("value",cookie.name);
@@ -166,7 +167,7 @@ function showhideinfo()
sizeToContent();
}
-function onChangePersitence()
+function onChangePersistence()
{
params.SetInt(nsICookieAcceptDialog.REMEMBER_DECISION, document.getElementById('persistDomainAcceptance').checked);
}
diff --git a/extensions/cookie/resources/content/cookieAcceptDialog.xul b/extensions/cookie/resources/content/cookieAcceptDialog.xul
index 8e472f4ea4ba..3f62dcbdb04d 100644
--- a/extensions/cookie/resources/content/cookieAcceptDialog.xul
+++ b/extensions/cookie/resources/content/cookieAcceptDialog.xul
@@ -70,8 +70,9 @@
-
+
diff --git a/extensions/cookie/resources/content/cookieNavigatorOverlay.xul b/extensions/cookie/resources/content/cookieNavigatorOverlay.xul
index 9b0a2f5e9dee..6b04076820ff 100644
--- a/extensions/cookie/resources/content/cookieNavigatorOverlay.xul
+++ b/extensions/cookie/resources/content/cookieNavigatorOverlay.xul
@@ -34,6 +34,7 @@
// both are necessary. popupmanager is just a special case
// of permissionmanager but does extra work on add/remove
+ const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
var permissionmanager;
var popupmanager;
@@ -54,6 +55,7 @@
// determine which items we need to hide or disable from the task menu
function CheckForVisibility()
{
+ var uri = getBrowser().currentURI;
// obtain access to permissionmanager and popupmanager
// (popup manager is a wrapper around permission that does extra work)
@@ -69,17 +71,17 @@
}
// determine current state (blocked or unblocked) and hide appropriate menu item
- var blocked;
+ var blocked = nsIPermissionManager.UNKNOWN_ACTION;
blocked =
- permissionmanager.testForBlocking(window._content.location, COOKIEPERMISSION);
- enableElement("AllowCookies", blocked);
- enableElement("BlockCookies", !blocked);
+ permissionmanager.testPermission(uri, nsIPermissionManager.COOKIE_TYPE);
+ enableElement("AllowCookies", blocked != nsIPermissionManager.ALLOW_ACTION);
+ enableElement("BlockCookies", blocked != nsIPermissionManager.DENY_ACTION);
blocked =
- permissionmanager.testForBlocking(window._content.location, IMAGEPERMISSION);
- enableElement("AllowImages", blocked);
- enableElement("BlockImages", !blocked);
+ permissionmanager.testPermission(uri, nsIPermissionManager.IMAGE_TYPE);
+ enableElement("AllowImages", blocked != nsIPermissionManager.ALLOW_ACTION);
+ enableElement("BlockImages", blocked != nsIPermissionManager.DENY_ACTION);
SetPopupMenuEnabledState();
@@ -104,30 +106,13 @@
}
function SetPopupMenuEnabledState() {
- var suitable = false;
- var blocked = false;
+ var blocked = nsIPermissionManager.UNKNOWN_ACTION;
var policy = pref.getBoolPref("dom.disable_open_during_load");
- suitable = popupmanager.testSuitability(getBrowser().currentURI);
- if (suitable) {
- if (!policy) // blacklist, test if there is a permission set
- blocked = (popupmanager.testPermission(getBrowser().currentURI) == Components.interfaces.nsIPopupWindowManager.DENY_POPUP);
- else { // whitelist, check if it is on list
- blocked = true;
- var enumerator = popupmanager.getEnumerator();
- while (enumerator.hasMoreElements()) {
- var permission = enumerator.getNext()
- .QueryInterface(Components.interfaces.nsIPermission);
- if (permission.capability && getBrowser().currentURI.host == permission.host) {
- blocked = false;
- break;
- }
- }
- }
- }
+ blocked = permissionmanager.testPermission(getBrowser().currentURI, nsIPermissionManager.POPUP_TYPE);
- enableElement("BlockPopups", suitable && !blocked);
- enableElement("AllowPopups", suitable && blocked);
+ enableElement("BlockPopups", blocked != nsIPermissionManager.DENY_ACTION);
+ enableElement("AllowPopups", blocked != nsIPermissionManager.ALLOW_ACTION);
enableElement("ManagePopups", true);
}
@@ -147,24 +132,25 @@
return;
}
var element;
+ var uri = getBrowser().currentURI;
switch (action) {
case "cookieAllow":
- permissionmanager.add(window._content.location, true, COOKIEPERMISSION);
+ permissionmanager.add(uri, nsIPermissionManager.COOKIE_TYPE, nsIPermissionManager.ALLOW_ACTION);
element = document.getElementById("AllowCookies");
alert(element.getAttribute("msg"));
break;
case "cookieBlock":
- permissionmanager.add(window._content.location, false, COOKIEPERMISSION);
+ permissionmanager.add(uri, nsIPermissionManager.COOKIE_TYPE, nsIPermissionManager.DENY_ACTION);
element = document.getElementById("BlockCookies");
alert(element.getAttribute("msg"));
break;
case "imageAllow":
- permissionmanager.add(window._content.location, true, IMAGEPERMISSION);
+ permissionmanager.add(uri, nsIPermissionManager.IMAGE_TYPE, nsIPermissionManager.ALLOW_ACTION);
element = document.getElementById("AllowImages");
alert(element.getAttribute("msg"));
break;
case "imageBlock":
- permissionmanager.add(window._content.location, false, IMAGEPERMISSION);
+ permissionmanager.add(uri, nsIPermissionManager.IMAGE_TYPE, nsIPermissionManager.DENY_ACTION);
element = document.getElementById("BlockImages");
alert(element.getAttribute("msg"));
break;
@@ -178,18 +164,12 @@
switch (action) {
case "block":
- if (!policy)
- popupmanager.add(uri, policy);
- else
- popupmanager.remove(uri);
+ permissionmanager.add(uri, nsIPermissionManager.POPUP_TYPE, nsIPermissionManager.DENY_ACTION);
break;
case "allow":
var browsers = getBrowser().browsers;
var popupIcon = document.getElementById("popupIcon");
- if (!policy)
- popupmanager.remove(uri);
- else
- popupmanager.add(uri, policy);
+ permissionmanager.add(uri, nsIPermissionManager.POPUP_TYPE, nsIPermissionManager.ALLOW_ACTION);
for (var i = 0; i < browsers.length; i++) {
if (browsers[i].popupDomain == uri.host) {
browsers[i].popupDomain = null;
diff --git a/toolkit/components/cookie/content/cookieAcceptDialog.js b/toolkit/components/cookie/content/cookieAcceptDialog.js
index 8963a694cf19..565b296d654e 100644
--- a/toolkit/components/cookie/content/cookieAcceptDialog.js
+++ b/toolkit/components/cookie/content/cookieAcceptDialog.js
@@ -126,7 +126,8 @@ function onload()
messageParent.appendChild(descriptionNode);
}
- document.getElementById('persistDomainAcceptance').checked = params.GetInt(nsICookieAcceptDialog.REMEMBER_DECISION) > 0;
+ // Must we remember the decision?
+ params.SetInt(nsICookieAcceptDialog.REMEMBER_DECISION, document.getElementById('persistDomainAcceptance').checked);
if (cookie) {
document.getElementById('ifl_name').setAttribute("value",cookie.name);
@@ -166,7 +167,7 @@ function showhideinfo()
sizeToContent();
}
-function onChangePersitence()
+function onChangePersistence()
{
params.SetInt(nsICookieAcceptDialog.REMEMBER_DECISION, document.getElementById('persistDomainAcceptance').checked);
}
diff --git a/toolkit/components/cookie/content/cookieAcceptDialog.xul b/toolkit/components/cookie/content/cookieAcceptDialog.xul
index 8e472f4ea4ba..3f62dcbdb04d 100644
--- a/toolkit/components/cookie/content/cookieAcceptDialog.xul
+++ b/toolkit/components/cookie/content/cookieAcceptDialog.xul
@@ -70,8 +70,9 @@
-
+
diff --git a/xpfe/appshell/public/nsIPopupWindowManager.idl b/xpfe/appshell/public/nsIPopupWindowManager.idl
index 4a7d3bb61c52..f11f1c9177c2 100644
--- a/xpfe/appshell/public/nsIPopupWindowManager.idl
+++ b/xpfe/appshell/public/nsIPopupWindowManager.idl
@@ -62,61 +62,12 @@ interface nsIPopupWindowManager : nsISupports {
*/
attribute PRUint32 defaultPermission;
- /**
- * Add permission information for a website.
- * @param aURI the website to be blocked
- * @param aPermit true to grant permission to the website
- * false to refuse permission
- */
- void add(in nsIURI aURI, in boolean aPermit);
-
- /**
- * Remove permission information for a website. Popups will be permitted
- * or not depending on whether this is a white- or black-list.
- * is permitted to show popups.)
- * @param aURI the website to be unblocked
- */
- void remove(in nsIURI aURI);
-
- /**
- * Clear permission information for all websites.
- */
- void removeAll();
-
- /**
- * Test whether a website is suitable for popup permission storage.
- * @param aURI the website to be tested
- * @return true if permission can be stored for the website
- */
- boolean testSuitability(in nsIURI aURI);
-
/**
* Test whether a website has permission to show a popup window.
- * @param aURI the website to be tested
- * @return one of the ALLOW/DENY consts defined above
+ * @param uri is the URI to be tested
+ * @return one of the enumerated permission actions defined above
*/
- PRUint32 testPermission(in nsIURI aURI);
-
- /**
- * Enumerates all stored permissions
- * @return an enumerator which itself returns nsISupports objects which
- * can be QIed to an nsIPermission
- */
- nsISimpleEnumerator getEnumerator();
-
- /**
- * This service broadcasts a PPM_CHANGE_NOTIFICATION notification
- * when any popup permission changes. Add yourself as an observer.
- * @param observer the observer
- */
- void addObserver(in nsIObserver aObserver);
-
- /**
- * This service broadcasts a PPM_CHANGE_NOTIFICATION notification
- * when any popup permission changes. Remove yourself as an observer.
- * @param observer the observer
- */
- void removeObserver(in nsIObserver aObserver);
+ PRUint32 testPermission(in nsIURI uri);
};
%{ C++
diff --git a/xpfe/communicator/resources/content/nsContextMenu.js b/xpfe/communicator/resources/content/nsContextMenu.js
index 734c83cb7694..a581f0f2f134 100644
--- a/xpfe/communicator/resources/content/nsContextMenu.js
+++ b/xpfe/communicator/resources/content/nsContextMenu.js
@@ -462,8 +462,6 @@ nsContextMenu.prototype = {
// but cancel if it's an unsuitable URL
const PM = Components.classes["@mozilla.org/PopupWindowManager;1"]
.getService(CI.nsIPopupWindowManager);
- if (!PM.testSuitability(this.popupURL))
- this.popupURL = null;
}
} catch(e) {
}
diff --git a/xpfe/communicator/resources/content/popupManager.js b/xpfe/communicator/resources/content/popupManager.js
index 49b71d6dc6fc..57edfeab404c 100644
--- a/xpfe/communicator/resources/content/popupManager.js
+++ b/xpfe/communicator/resources/content/popupManager.js
@@ -21,7 +21,11 @@
*
* ***** END LICENSE BLOCK ***** */
+const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
+const popupType = nsIPermissionManager.POPUP_TYPE;
+
var popupManager = null;
+var permissionManager = null;
var permissions = [];
@@ -31,8 +35,6 @@ var listCapability; // the capability of sites on the currently viewed list
// FALSE: current popup policy is ALLOW ALL WITH EXCEPTIONS - sites on
// the blacklist are blocked and have permission.capability = false
-const POPUP_TYPE = 2;
-
var additions = [];
var removals = [];
@@ -66,6 +68,8 @@ var popupStringBundle;
function Startup() {
popupManager = Components.classes["@mozilla.org/PopupWindowManager;1"]
.getService(Components.interfaces.nsIPopupWindowManager);
+ permissionManager = Components.classes["@mozilla.org/permissionmanager;1"]
+ .getService(Components.interfaces.nsIPermissionManager);
permissionsTree = document.getElementById("permissionsTree");
@@ -204,15 +208,18 @@ function Permission(host, number) {
}
function loadPermissions(table) {
- var enumerator = popupManager.getEnumerator();
+ var enumerator = permissionManager.enumerator;
var count = 0;
while (enumerator.hasMoreElements()) {
- var permission = enumerator.getNext()
- .QueryInterface(Components.interfaces.nsIPermission);
- if (permission.capability == listCapability) {
- var host = permission.host;
- table[count] = new Permission(host,count++);
+ var permission = enumerator.getNext();
+ if (permission) {
+ permission = permission.QueryInterface(Components.interfaces.nsIPermission);
+ if ((permission.type == popupType) &&
+ (permission.capability == listCapability)) {
+ var host = permission.host;
+ table[count] = new Permission(host,count++);
+ }
}
}
}
@@ -297,7 +304,7 @@ function deleteAllPermissions() {
}
function updatePendingRemovals(host) {
- if (additions[host] != null)
+ if (additions[host])
additions[host] = null;
else
removals[host] = host;
@@ -317,23 +324,26 @@ function finalizeChanges() {
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
+ var uri;
+ var host;
+ var i;
+
+ var perm = (listCapability == true) ? nsIPermissionManager.ALLOW_ACTION : nsIPermissionManager.DENY_ACTION
//note: the scheme will be taken off later, it is being added now only to
//create the uri for add/remove
- for (var i in additions) {
- var host = additions[i];
+ for (i in additions) {
+ host = additions[i];
if (host != null) {
host = "http://" + host;
- var uri = ioService.newURI(host, null, null);
- popupManager.add(uri, listCapability);
+ uri = ioService.newURI(host, null, null);
+ permissionManager.add(uri, popupType, listCapability);
}
}
- for (var i in removals) {
- var host = removals[i];
+ for (i in removals) {
+ host = removals[i];
if (host != null) {
- host = "http://" + host;
- var uri = ioService.newURI(host, null, null);
- popupManager.remove(uri);
+ permissionManager.remove(host, popupType);
}
}
diff --git a/xpfe/components/permissions/content/permissionsManager.js b/xpfe/components/permissions/content/permissionsManager.js
index 49b71d6dc6fc..57edfeab404c 100644
--- a/xpfe/components/permissions/content/permissionsManager.js
+++ b/xpfe/components/permissions/content/permissionsManager.js
@@ -21,7 +21,11 @@
*
* ***** END LICENSE BLOCK ***** */
+const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
+const popupType = nsIPermissionManager.POPUP_TYPE;
+
var popupManager = null;
+var permissionManager = null;
var permissions = [];
@@ -31,8 +35,6 @@ var listCapability; // the capability of sites on the currently viewed list
// FALSE: current popup policy is ALLOW ALL WITH EXCEPTIONS - sites on
// the blacklist are blocked and have permission.capability = false
-const POPUP_TYPE = 2;
-
var additions = [];
var removals = [];
@@ -66,6 +68,8 @@ var popupStringBundle;
function Startup() {
popupManager = Components.classes["@mozilla.org/PopupWindowManager;1"]
.getService(Components.interfaces.nsIPopupWindowManager);
+ permissionManager = Components.classes["@mozilla.org/permissionmanager;1"]
+ .getService(Components.interfaces.nsIPermissionManager);
permissionsTree = document.getElementById("permissionsTree");
@@ -204,15 +208,18 @@ function Permission(host, number) {
}
function loadPermissions(table) {
- var enumerator = popupManager.getEnumerator();
+ var enumerator = permissionManager.enumerator;
var count = 0;
while (enumerator.hasMoreElements()) {
- var permission = enumerator.getNext()
- .QueryInterface(Components.interfaces.nsIPermission);
- if (permission.capability == listCapability) {
- var host = permission.host;
- table[count] = new Permission(host,count++);
+ var permission = enumerator.getNext();
+ if (permission) {
+ permission = permission.QueryInterface(Components.interfaces.nsIPermission);
+ if ((permission.type == popupType) &&
+ (permission.capability == listCapability)) {
+ var host = permission.host;
+ table[count] = new Permission(host,count++);
+ }
}
}
}
@@ -297,7 +304,7 @@ function deleteAllPermissions() {
}
function updatePendingRemovals(host) {
- if (additions[host] != null)
+ if (additions[host])
additions[host] = null;
else
removals[host] = host;
@@ -317,23 +324,26 @@ function finalizeChanges() {
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
+ var uri;
+ var host;
+ var i;
+
+ var perm = (listCapability == true) ? nsIPermissionManager.ALLOW_ACTION : nsIPermissionManager.DENY_ACTION
//note: the scheme will be taken off later, it is being added now only to
//create the uri for add/remove
- for (var i in additions) {
- var host = additions[i];
+ for (i in additions) {
+ host = additions[i];
if (host != null) {
host = "http://" + host;
- var uri = ioService.newURI(host, null, null);
- popupManager.add(uri, listCapability);
+ uri = ioService.newURI(host, null, null);
+ permissionManager.add(uri, popupType, listCapability);
}
}
- for (var i in removals) {
- var host = removals[i];
+ for (i in removals) {
+ host = removals[i];
if (host != null) {
- host = "http://" + host;
- var uri = ioService.newURI(host, null, null);
- popupManager.remove(uri);
+ permissionManager.remove(host, popupType);
}
}
diff --git a/xpfe/components/permissions/content/permissionsNavigatorOverlay.xul b/xpfe/components/permissions/content/permissionsNavigatorOverlay.xul
index 9b0a2f5e9dee..6b04076820ff 100644
--- a/xpfe/components/permissions/content/permissionsNavigatorOverlay.xul
+++ b/xpfe/components/permissions/content/permissionsNavigatorOverlay.xul
@@ -34,6 +34,7 @@
// both are necessary. popupmanager is just a special case
// of permissionmanager but does extra work on add/remove
+ const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
var permissionmanager;
var popupmanager;
@@ -54,6 +55,7 @@
// determine which items we need to hide or disable from the task menu
function CheckForVisibility()
{
+ var uri = getBrowser().currentURI;
// obtain access to permissionmanager and popupmanager
// (popup manager is a wrapper around permission that does extra work)
@@ -69,17 +71,17 @@
}
// determine current state (blocked or unblocked) and hide appropriate menu item
- var blocked;
+ var blocked = nsIPermissionManager.UNKNOWN_ACTION;
blocked =
- permissionmanager.testForBlocking(window._content.location, COOKIEPERMISSION);
- enableElement("AllowCookies", blocked);
- enableElement("BlockCookies", !blocked);
+ permissionmanager.testPermission(uri, nsIPermissionManager.COOKIE_TYPE);
+ enableElement("AllowCookies", blocked != nsIPermissionManager.ALLOW_ACTION);
+ enableElement("BlockCookies", blocked != nsIPermissionManager.DENY_ACTION);
blocked =
- permissionmanager.testForBlocking(window._content.location, IMAGEPERMISSION);
- enableElement("AllowImages", blocked);
- enableElement("BlockImages", !blocked);
+ permissionmanager.testPermission(uri, nsIPermissionManager.IMAGE_TYPE);
+ enableElement("AllowImages", blocked != nsIPermissionManager.ALLOW_ACTION);
+ enableElement("BlockImages", blocked != nsIPermissionManager.DENY_ACTION);
SetPopupMenuEnabledState();
@@ -104,30 +106,13 @@
}
function SetPopupMenuEnabledState() {
- var suitable = false;
- var blocked = false;
+ var blocked = nsIPermissionManager.UNKNOWN_ACTION;
var policy = pref.getBoolPref("dom.disable_open_during_load");
- suitable = popupmanager.testSuitability(getBrowser().currentURI);
- if (suitable) {
- if (!policy) // blacklist, test if there is a permission set
- blocked = (popupmanager.testPermission(getBrowser().currentURI) == Components.interfaces.nsIPopupWindowManager.DENY_POPUP);
- else { // whitelist, check if it is on list
- blocked = true;
- var enumerator = popupmanager.getEnumerator();
- while (enumerator.hasMoreElements()) {
- var permission = enumerator.getNext()
- .QueryInterface(Components.interfaces.nsIPermission);
- if (permission.capability && getBrowser().currentURI.host == permission.host) {
- blocked = false;
- break;
- }
- }
- }
- }
+ blocked = permissionmanager.testPermission(getBrowser().currentURI, nsIPermissionManager.POPUP_TYPE);
- enableElement("BlockPopups", suitable && !blocked);
- enableElement("AllowPopups", suitable && blocked);
+ enableElement("BlockPopups", blocked != nsIPermissionManager.DENY_ACTION);
+ enableElement("AllowPopups", blocked != nsIPermissionManager.ALLOW_ACTION);
enableElement("ManagePopups", true);
}
@@ -147,24 +132,25 @@
return;
}
var element;
+ var uri = getBrowser().currentURI;
switch (action) {
case "cookieAllow":
- permissionmanager.add(window._content.location, true, COOKIEPERMISSION);
+ permissionmanager.add(uri, nsIPermissionManager.COOKIE_TYPE, nsIPermissionManager.ALLOW_ACTION);
element = document.getElementById("AllowCookies");
alert(element.getAttribute("msg"));
break;
case "cookieBlock":
- permissionmanager.add(window._content.location, false, COOKIEPERMISSION);
+ permissionmanager.add(uri, nsIPermissionManager.COOKIE_TYPE, nsIPermissionManager.DENY_ACTION);
element = document.getElementById("BlockCookies");
alert(element.getAttribute("msg"));
break;
case "imageAllow":
- permissionmanager.add(window._content.location, true, IMAGEPERMISSION);
+ permissionmanager.add(uri, nsIPermissionManager.IMAGE_TYPE, nsIPermissionManager.ALLOW_ACTION);
element = document.getElementById("AllowImages");
alert(element.getAttribute("msg"));
break;
case "imageBlock":
- permissionmanager.add(window._content.location, false, IMAGEPERMISSION);
+ permissionmanager.add(uri, nsIPermissionManager.IMAGE_TYPE, nsIPermissionManager.DENY_ACTION);
element = document.getElementById("BlockImages");
alert(element.getAttribute("msg"));
break;
@@ -178,18 +164,12 @@
switch (action) {
case "block":
- if (!policy)
- popupmanager.add(uri, policy);
- else
- popupmanager.remove(uri);
+ permissionmanager.add(uri, nsIPermissionManager.POPUP_TYPE, nsIPermissionManager.DENY_ACTION);
break;
case "allow":
var browsers = getBrowser().browsers;
var popupIcon = document.getElementById("popupIcon");
- if (!policy)
- popupmanager.remove(uri);
- else
- popupmanager.add(uri, policy);
+ permissionmanager.add(uri, nsIPermissionManager.POPUP_TYPE, nsIPermissionManager.ALLOW_ACTION);
for (var i = 0; i < browsers.length; i++) {
if (browsers[i].popupDomain == uri.host) {
browsers[i].popupDomain = null;