xpcom/glue/nsCategoryCache.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* vim:set st=2 sts=2 ts=2 et cin: */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "nsIObserverService.h"
michael@0 7 #include "mozilla/Services.h"
michael@0 8 #include "nsISupportsPrimitives.h"
michael@0 9 #include "nsIStringEnumerator.h"
michael@0 10
michael@0 11 #include "nsXPCOMCID.h"
michael@0 12
michael@0 13 #include "nsCategoryCache.h"
michael@0 14
michael@0 15 nsCategoryObserver::nsCategoryObserver(const char* aCategory)
michael@0 16 : mCategory(aCategory)
michael@0 17 , mObserversRemoved(false)
michael@0 18 {
michael@0 19 // First, enumerate the currently existing entries
michael@0 20 nsCOMPtr<nsICategoryManager> catMan =
michael@0 21 do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
michael@0 22 if (!catMan)
michael@0 23 return;
michael@0 24
michael@0 25 nsCOMPtr<nsISimpleEnumerator> enumerator;
michael@0 26 nsresult rv = catMan->EnumerateCategory(aCategory,
michael@0 27 getter_AddRefs(enumerator));
michael@0 28 if (NS_FAILED(rv))
michael@0 29 return;
michael@0 30
michael@0 31 nsCOMPtr<nsIUTF8StringEnumerator> strings = do_QueryInterface(enumerator);
michael@0 32 MOZ_ASSERT(strings);
michael@0 33
michael@0 34 bool more;
michael@0 35 while (NS_SUCCEEDED(strings->HasMore(&more)) && more) {
michael@0 36 nsAutoCString entryName;
michael@0 37 strings->GetNext(entryName);
michael@0 38
michael@0 39 nsCString entryValue;
michael@0 40 rv = catMan->GetCategoryEntry(aCategory,
michael@0 41 entryName.get(),
michael@0 42 getter_Copies(entryValue));
michael@0 43 if (NS_SUCCEEDED(rv)) {
michael@0 44 nsCOMPtr<nsISupports> service = do_GetService(entryValue.get());
michael@0 45 if (service) {
michael@0 46 mHash.Put(entryName, service);
michael@0 47 }
michael@0 48 }
michael@0 49 }
michael@0 50
michael@0 51 // Now, listen for changes
michael@0 52 nsCOMPtr<nsIObserverService> serv =
michael@0 53 mozilla::services::GetObserverService();
michael@0 54 if (serv) {
michael@0 55 serv->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
michael@0 56 serv->AddObserver(this, NS_XPCOM_CATEGORY_ENTRY_ADDED_OBSERVER_ID, false);
michael@0 57 serv->AddObserver(this, NS_XPCOM_CATEGORY_ENTRY_REMOVED_OBSERVER_ID, false);
michael@0 58 serv->AddObserver(this, NS_XPCOM_CATEGORY_CLEARED_OBSERVER_ID, false);
michael@0 59 }
michael@0 60 }
michael@0 61
michael@0 62 nsCategoryObserver::~nsCategoryObserver() {
michael@0 63 }
michael@0 64
michael@0 65 NS_IMPL_ISUPPORTS(nsCategoryObserver, nsIObserver)
michael@0 66
michael@0 67 void
michael@0 68 nsCategoryObserver::ListenerDied() {
michael@0 69 RemoveObservers();
michael@0 70 }
michael@0 71
michael@0 72 void
michael@0 73 nsCategoryObserver::RemoveObservers() {
michael@0 74 if (mObserversRemoved)
michael@0 75 return;
michael@0 76
michael@0 77 mObserversRemoved = true;
michael@0 78 nsCOMPtr<nsIObserverService> obsSvc =
michael@0 79 mozilla::services::GetObserverService();
michael@0 80 if (obsSvc) {
michael@0 81 obsSvc->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
michael@0 82 obsSvc->RemoveObserver(this, NS_XPCOM_CATEGORY_ENTRY_ADDED_OBSERVER_ID);
michael@0 83 obsSvc->RemoveObserver(this, NS_XPCOM_CATEGORY_ENTRY_REMOVED_OBSERVER_ID);
michael@0 84 obsSvc->RemoveObserver(this, NS_XPCOM_CATEGORY_CLEARED_OBSERVER_ID);
michael@0 85 }
michael@0 86 }
michael@0 87
michael@0 88 NS_IMETHODIMP
michael@0 89 nsCategoryObserver::Observe(nsISupports* aSubject, const char* aTopic,
michael@0 90 const char16_t* aData) {
michael@0 91 if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
michael@0 92 mHash.Clear();
michael@0 93 RemoveObservers();
michael@0 94
michael@0 95 return NS_OK;
michael@0 96 }
michael@0 97
michael@0 98 if (!aData ||
michael@0 99 !nsDependentString(aData).Equals(NS_ConvertASCIItoUTF16(mCategory)))
michael@0 100 return NS_OK;
michael@0 101
michael@0 102 nsAutoCString str;
michael@0 103 nsCOMPtr<nsISupportsCString> strWrapper(do_QueryInterface(aSubject));
michael@0 104 if (strWrapper)
michael@0 105 strWrapper->GetData(str);
michael@0 106
michael@0 107 if (strcmp(aTopic, NS_XPCOM_CATEGORY_ENTRY_ADDED_OBSERVER_ID) == 0) {
michael@0 108 // We may get an add notification even when we already have an entry. This
michael@0 109 // is due to the notification happening asynchronously, so if the entry gets
michael@0 110 // added and an nsCategoryObserver gets instantiated before events get
michael@0 111 // processed, we'd get the notification for an existing entry.
michael@0 112 // Do nothing in that case.
michael@0 113 if (mHash.GetWeak(str))
michael@0 114 return NS_OK;
michael@0 115
michael@0 116 nsCOMPtr<nsICategoryManager> catMan =
michael@0 117 do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
michael@0 118 if (!catMan)
michael@0 119 return NS_OK;
michael@0 120
michael@0 121 nsCString entryValue;
michael@0 122 catMan->GetCategoryEntry(mCategory.get(),
michael@0 123 str.get(),
michael@0 124 getter_Copies(entryValue));
michael@0 125
michael@0 126 nsCOMPtr<nsISupports> service = do_GetService(entryValue.get());
michael@0 127
michael@0 128 if (service) {
michael@0 129 mHash.Put(str, service);
michael@0 130 }
michael@0 131 } else if (strcmp(aTopic, NS_XPCOM_CATEGORY_ENTRY_REMOVED_OBSERVER_ID) == 0) {
michael@0 132 mHash.Remove(str);
michael@0 133 } else if (strcmp(aTopic, NS_XPCOM_CATEGORY_CLEARED_OBSERVER_ID) == 0) {
michael@0 134 mHash.Clear();
michael@0 135 }
michael@0 136 return NS_OK;
michael@0 137 }

mercurial