UrlClassifierExceptionListEntry.cpp (6913B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "UrlClassifierExceptionListEntry.h" 8 #include "mozilla/ErrorResult.h" 9 #include "mozilla/StaticPrefs_privacy.h" 10 11 namespace mozilla::net { 12 13 NS_IMPL_ISUPPORTS(UrlClassifierExceptionListEntry, 14 nsIUrlClassifierExceptionListEntry) 15 16 NS_IMETHODIMP 17 UrlClassifierExceptionListEntry::Init( 18 nsIUrlClassifierExceptionListEntry::Category aCategory, 19 const nsACString& aUrlPattern, const nsACString& aTopLevelUrlPattern, 20 bool aIsPrivateBrowsingOnly, 21 const nsTArray<nsCString>& aFilterContentBlockingCategories, 22 const nsTArray<nsCString>& aClassifierFeatures) { 23 // Validate category. 24 NS_ENSURE_TRUE( 25 aCategory == nsIUrlClassifierExceptionListEntry::Category:: 26 CATEGORY_INTERNAL_PREF || 27 aCategory == 28 nsIUrlClassifierExceptionListEntry::Category::CATEGORY_BASELINE || 29 aCategory == nsIUrlClassifierExceptionListEntry::Category:: 30 CATEGORY_CONVENIENCE, 31 NS_ERROR_INVALID_ARG); 32 mCategory = aCategory; 33 mUrlPattern = aUrlPattern; 34 mTopLevelUrlPattern = aTopLevelUrlPattern; 35 mIsPrivateBrowsingOnly = aIsPrivateBrowsingOnly; 36 mFilterContentBlockingCategories = aFilterContentBlockingCategories.Clone(); 37 mClassifierFeatures = aClassifierFeatures.Clone(); 38 39 // Create pattern from urlPattern and topLevelUrlPattern strings. 40 ErrorResult error; 41 mMatcher = new extensions::MatchPatternCore( 42 NS_ConvertUTF8toUTF16(mUrlPattern), false, false, error); 43 RETURN_NSRESULT_ON_FAILURE(error); 44 45 if (!mTopLevelUrlPattern.IsEmpty()) { 46 mTopLevelMatcher = new extensions::MatchPatternCore( 47 NS_ConvertUTF8toUTF16(mTopLevelUrlPattern), false, false, error); 48 RETURN_NSRESULT_ON_FAILURE(error); 49 } 50 return NS_OK; 51 } 52 53 NS_IMETHODIMP 54 UrlClassifierExceptionListEntry::Matches(nsIURI* aURI, nsIURI* aTopLevelURI, 55 bool aIsPrivateBrowsing, 56 bool* aResult) { 57 NS_ENSURE_ARG_POINTER(aURI); 58 NS_ENSURE_ARG_POINTER(aResult); 59 *aResult = false; 60 61 MOZ_ASSERT( 62 mCategory == nsIUrlClassifierExceptionListEntry::Category:: 63 CATEGORY_INTERNAL_PREF || 64 mCategory == 65 nsIUrlClassifierExceptionListEntry::Category::CATEGORY_BASELINE || 66 mCategory == 67 nsIUrlClassifierExceptionListEntry::Category::CATEGORY_CONVENIENCE); 68 69 // If the entry category is not internal pref, we need to check if the 70 // baseline and convenience exceptions are enabled. 71 if (mCategory != 72 nsIUrlClassifierExceptionListEntry::Category::CATEGORY_INTERNAL_PREF) { 73 bool baselineEnabled = 74 StaticPrefs::privacy_trackingprotection_allow_list_baseline_enabled(); 75 bool convenienceEnabled = StaticPrefs:: 76 privacy_trackingprotection_allow_list_convenience_enabled(); 77 78 // If baseline is disabled, we should not allow convenience exceptions 79 // either. 80 if (!baselineEnabled) { 81 convenienceEnabled = false; 82 } 83 84 // Check if the entry category is enabled. CATEGORY_INTERNAL_PREF always 85 // applies. 86 if ((mCategory == 87 nsIUrlClassifierExceptionListEntry::Category::CATEGORY_BASELINE && 88 !baselineEnabled) || 89 (mCategory == nsIUrlClassifierExceptionListEntry::Category:: 90 CATEGORY_CONVENIENCE && 91 !convenienceEnabled)) { 92 return NS_OK; 93 } 94 } 95 96 // Entry is scoped to private browsing only and we're not in private browsing. 97 if (!aIsPrivateBrowsing && mIsPrivateBrowsingOnly) { 98 return NS_OK; 99 } 100 101 // Next, check if the current content blocking category pref matches the 102 // allowed content blocking categories for this exception entry. 103 if (!mFilterContentBlockingCategories.IsEmpty()) { 104 nsCString prefValue; 105 nsresult rv = 106 Preferences::GetCString("browser.contentblocking.category", prefValue); 107 108 // If the pref is not set this check is skipped. 109 if (NS_SUCCEEDED(rv) && !prefValue.IsEmpty()) { 110 if (!mFilterContentBlockingCategories.Contains(prefValue)) { 111 return NS_OK; 112 } 113 } 114 } 115 116 // Check if the load URI matches the urlPattern. 117 if (!mMatcher->Matches(aURI)) { 118 return NS_OK; 119 } 120 121 // If this entry filters for top level site, check if the top level URI 122 // matches the topLevelUrlPattern. If the entry filters for top level site, 123 // but the caller does not provide one, we will not match. 124 if (mTopLevelMatcher && 125 (!aTopLevelURI || !mTopLevelMatcher->Matches(aTopLevelURI))) { 126 return NS_OK; 127 } 128 129 *aResult = true; 130 return NS_OK; 131 } 132 133 NS_IMETHODIMP 134 UrlClassifierExceptionListEntry::GetCategory( 135 nsIUrlClassifierExceptionListEntry::Category* aCategory) { 136 *aCategory = mCategory; 137 return NS_OK; 138 } 139 140 NS_IMETHODIMP 141 UrlClassifierExceptionListEntry::GetUrlPattern(nsACString& aUrlPattern) { 142 aUrlPattern = mUrlPattern; 143 return NS_OK; 144 } 145 146 NS_IMETHODIMP 147 UrlClassifierExceptionListEntry::GetTopLevelUrlPattern( 148 nsACString& aTopLevelUrlPattern) { 149 aTopLevelUrlPattern = mTopLevelUrlPattern; 150 return NS_OK; 151 } 152 153 NS_IMETHODIMP 154 UrlClassifierExceptionListEntry::GetIsPrivateBrowsingOnly( 155 bool* aIsPrivateBrowsingOnly) { 156 *aIsPrivateBrowsingOnly = mIsPrivateBrowsingOnly; 157 return NS_OK; 158 } 159 160 NS_IMETHODIMP 161 UrlClassifierExceptionListEntry::GetFilterContentBlockingCategories( 162 nsTArray<nsCString>& aFilterContentBlockingCategories) { 163 aFilterContentBlockingCategories = mFilterContentBlockingCategories.Clone(); 164 return NS_OK; 165 } 166 167 NS_IMETHODIMP 168 UrlClassifierExceptionListEntry::GetClassifierFeatures( 169 nsTArray<nsCString>& aClassifierFeatures) { 170 aClassifierFeatures = mClassifierFeatures.Clone(); 171 return NS_OK; 172 } 173 174 NS_IMETHODIMP 175 UrlClassifierExceptionListEntry::Describe(nsACString& aDescription) { 176 nsAutoCString categories; 177 for (const auto& category : mFilterContentBlockingCategories) { 178 if (!categories.IsEmpty()) { 179 categories.AppendLiteral(", "); 180 } 181 categories.Append(category); 182 } 183 184 nsAutoCString classifierFeatures; 185 for (const auto& feature : mClassifierFeatures) { 186 if (!classifierFeatures.IsEmpty()) { 187 classifierFeatures.AppendLiteral(", "); 188 } 189 classifierFeatures.Append(feature); 190 } 191 192 aDescription.AppendPrintf( 193 "UrlClassifierExceptionListEntry(urlPattern='%s', " 194 "topLevelUrlPattern='%s', isPrivateBrowsingOnly=%s, " 195 "filterContentBlockingCategories=[%s], classifierFeatures=[%s])", 196 mUrlPattern.get(), mTopLevelUrlPattern.get(), 197 mIsPrivateBrowsingOnly ? "true" : "false", categories.get(), 198 classifierFeatures.get()); 199 200 return NS_OK; 201 } 202 203 } // namespace mozilla::net