2 * Copyright 2018-2019, 2021-2024 Soren Stoutner <soren@stoutner.com>.
4 * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
6 * Privacy Browser Android is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * Privacy Browser Android is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Privacy Browser Android. If not, see <http://www.gnu.org/licenses/>.
20 package com.stoutner.privacybrowser.helpers
22 import android.content.res.AssetManager
24 import java.io.BufferedReader
25 import java.io.IOException
26 import java.io.InputStreamReader
28 import java.util.ArrayList
30 // Define the schema of the string array in each entry of the resource requests array list.
31 const val REQUEST_DISPOSITION = 0
32 const val REQUEST_URL = 1
33 const val REQUEST_BLOCKLIST = 2
34 const val REQUEST_SUBLIST = 3
35 const val REQUEST_BLOCKLIST_ENTRIES = 4
36 const val REQUEST_BLOCKLIST_ORIGINAL_ENTRY = 5
38 // Define the allow lists.
39 const val MAIN_ALLOWLIST = "1"
40 const val FINAL_ALLOWLIST = "2"
41 const val DOMAIN_ALLOWLIST = "3"
42 const val DOMAIN_INITIAL_ALLOWLIST = "4"
43 const val DOMAIN_FINAL_ALLOWLIST = "5"
44 const val THIRD_PARTY_ALLOWLIST = "6"
45 const val THIRD_PARTY_DOMAIN_ALLOWLIST = "7"
46 const val THIRD_PARTY_DOMAIN_INITIAL_ALLOWLIST = "8"
48 // Define the block lists.
49 const val MAIN_BLOCKLIST = "9"
50 const val INITIAL_BLOCKLIST = "10"
51 const val FINAL_BLOCKLIST = "11"
52 const val DOMAIN_BLOCKLIST = "12"
53 const val DOMAIN_INITIAL_BLOCKLIST = "13"
54 const val DOMAIN_FINAL_BLOCKLIST = "14"
55 const val DOMAIN_REGULAR_EXPRESSION_BLOCKLIST = "15"
56 const val THIRD_PARTY_BLOCKLIST = "16"
57 const val THIRD_PARTY_INITIAL_BLOCKLIST = "17"
58 const val THIRD_PARTY_DOMAIN_BLOCKLIST = "18"
59 const val THIRD_PARTY_DOMAIN_INITIAL_BLOCKLIST = "19"
60 const val THIRD_PARTY_REGULAR_EXPRESSION_BLOCKLIST = "20"
61 const val THIRD_PARTY_DOMAIN_REGULAR_EXPRESSION_BLOCKLIST = "21"
62 const val REGULAR_EXPRESSION_BLOCKLIST = "22"
64 class ParseFilterListHelper {
65 fun parseFilterList(assetManager: AssetManager, filterListName: String): ArrayList<List<Array<String>>> {
66 // Initialize the header list.
67 val headers: MutableList<Array<String>> = ArrayList() // 0.
69 // Initialize the allow lists.
70 val mainAllowList: MutableList<Array<String>> = ArrayList() // 1.
71 val finalAllowList: MutableList<Array<String>> = ArrayList() // 2.
72 val domainAllowList: MutableList<Array<String>> = ArrayList() // 3.
73 val domainInitialAllowList: MutableList<Array<String>> = ArrayList() // 4.
74 val domainFinalAllowList: MutableList<Array<String>> = ArrayList() // 5.
75 val thirdPartyAllowList: MutableList<Array<String>> = ArrayList() // 6.
76 val thirdPartyDomainAllowList: MutableList<Array<String>> = ArrayList() // 7.
77 val thirdPartyDomainInitialAllowList: MutableList<Array<String>> = ArrayList() // 8.
79 // Initialize the block lists.
80 val mainBlockList: MutableList<Array<String>> = ArrayList() // 9.
81 val initialBlockList: MutableList<Array<String>> = ArrayList() // 10.
82 val finalBlockList: MutableList<Array<String>> = ArrayList() // 11.
83 val domainBlockList: MutableList<Array<String>> = ArrayList() // 12.
84 val domainInitialBlockList: MutableList<Array<String>> = ArrayList() // 13.
85 val domainFinalBlockList: MutableList<Array<String>> = ArrayList() // 14.
86 val domainRegularExpressionBlockList: MutableList<Array<String>> = ArrayList() // 15.
87 val thirdPartyBlockList: MutableList<Array<String>> = ArrayList() // 16.
88 val thirdPartyInitialBlockList: MutableList<Array<String>> = ArrayList() // 17.
89 val thirdPartyDomainBlockList: MutableList<Array<String>> = ArrayList() // 18.
90 val thirdPartyDomainInitialBlockList: MutableList<Array<String>> = ArrayList() // 19.
91 val regularExpressionBlockList: MutableList<Array<String>> = ArrayList() // 20.
92 val thirdPartyRegularExpressionBlockList: MutableList<Array<String>> = ArrayList() // 21.
93 val thirdPartyDomainRegularExpressionBlockList: MutableList<Array<String>> = ArrayList() // 22.
95 // Parse the filter list. The `try` is required by input stream reader.
97 // Load the filter list into a buffered reader.
98 val bufferedReader = BufferedReader(InputStreamReader(assetManager.open(filterListName)))
100 // Create strings for storing the filter list entries.
101 var filterListEntry: String
102 var originalFilterListEntry: String
104 // Parse the filter list.
105 bufferedReader.forEachLine {
106 // Store the original filter list entry.
107 originalFilterListEntry = it
109 // Remove any `^` from the filter list entry. Privacy Browser does not process them in the interest of efficiency.
110 filterListEntry = it.replace("^", "")
113 if (filterListEntry.contains("##") || filterListEntry.contains("#?#") || filterListEntry.contains("#@#") || filterListEntry.startsWith("[")) {
114 // Entries that contain `##`, `#?#`, and `#@#` are for hiding elements in the main page's HTML. Entries that start with `[` describe the AdBlock compatibility level.
115 // Do nothing. Privacy Browser does not currently use these entries.
117 //Log.i("FilterLists", "Not added: " + filterListEntry)
118 } else if (filterListEntry.contains("\$csp=script-src")) { // Ignore entries that contain `$csp=script-src`.
119 // Do nothing. It is uncertain what this directive is even supposed to mean, and it is blocking entire websites like androidcentral.com. https://redmine.stoutner.com/issues/306.
121 //Log.i("FilterLists", "Not added: " + originalFilterListEntry)
122 } else if (filterListEntry.contains("\$websocket") || filterListEntry.contains("\$third-party,websocket") || filterListEntry.contains("\$script,websocket")) {
123 // Ignore entries with `websocket`.
124 // Do nothing. Privacy Browser does not differentiate between websocket requests and other requests and these entries cause a lot of false positives.
126 //Log.i("FilterLists", "Not added: " + originalFilterlistEntry)
127 } else if (filterListEntry.startsWith("!")) { // Comment entries.
128 if (filterListEntry.startsWith("! Version:")) {
129 // Get the list version number.
130 val listVersion = arrayOf(filterListEntry.substring(11))
132 // Store the list version in the headers list.
133 headers.add(listVersion)
136 if (filterListEntry.startsWith("! Title:")) {
137 // Get the list title.
138 val listTitle = arrayOf(filterListEntry.substring(9))
140 // Store the list title in the headers list.
141 headers.add(listTitle)
144 //Log.i("FilterLists", "Not added: " + filterListEntry);
145 } else if (filterListEntry.startsWith("@@")) { // Entries that begin with `@@` are allowed entries.
147 filterListEntry = filterListEntry.substring(2)
149 // Strip out any initial `||`. Privacy Browser doesn't differentiate items that only match against the end of the domain name.
150 if (filterListEntry.startsWith("||"))
151 filterListEntry = filterListEntry.substring(2)
153 // Check if the entry contains an Adblock filter option (indicated by `$`).
154 if (filterListEntry.contains("$")) { // The entry contains a filter option.
155 if (filterListEntry.contains("~third-party")) { // Ignore entries that contain `~third-party`.
158 //Log.i("FilterLists", headers.get(1)[0] + " not added: " + originalFilterListEntry)
159 } else if (filterListEntry.contains("third-party")) { // Third-party allowed entries.
160 // Check if the entry only applies to certain domains.
161 if (filterListEntry.contains("domain=")) { // Third-party domain allowed entries.
163 var entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
164 val filters = filterListEntry.substring(filterListEntry.indexOf("$") + 1)
165 var domains = filters.substring(filters.indexOf("domain=") + 7)
167 if (domains.contains("~")) { // It is uncertain what a `~` domain means inside an `@@` entry.
170 //Log.i("FilterLists", headers.get(1)[0] + " not added: " + originalFilterListEntry)
171 } else if (filterListEntry.startsWith("|")) { // Third-party domain initial allowed entries.
172 // Strip out the initial `|`.
173 entry = entry.substring(1)
175 if (entry == "http://" || entry == "https://") { // Ignore generic entries.
176 // Do nothing. These entries are designed for filter options that Privacy Browser does not use.
178 //Log.i("FilterLists", headers.get(1)[0] + " not added: " + originalFilterListEntry);
179 } else { // Process third-party domain initial allowed entries.
180 // Process each domain.
182 // Create a string to keep track of the current domain.
185 // Populate the current domain.
186 if (domains.contains("|")) { // There is more than one domain in the list.
187 // Get the first domain from the list.
188 domain = domains.substring(0, domains.indexOf("|"))
190 // Remove the first domain from the list.
191 domains = domains.substring(domains.indexOf("|") + 1)
192 } else { // There is only one domain in the list.
196 // Process the domain entry.
197 if (entry.contains("*")) { // Process a third-party domain initial allowed double entry.
198 // Get the index of the wildcard.
199 val wildcardIndex = entry.indexOf("*")
201 // Split the entry into components.
202 val firstEntry = entry.substring(0, wildcardIndex)
203 val secondEntry = entry.substring(wildcardIndex + 1)
205 // Create an entry string array.
206 val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
208 // Add the entry to the allow list.
209 thirdPartyDomainInitialAllowList.add(domainDoubleEntry)
211 //Log.i("FilterLists", headers.get(1)[0] + " third-party domain initial allow list added: " + domain + " , " + firstEntry + " , " + secondEntry +
212 // " - " + originalFilterListEntry)
213 } else { // Process a third-party domain initial allowed single entry.
214 // Create a domain entry string array.
215 val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
217 // Add the entry to the third party domain initial allow list.
218 thirdPartyDomainInitialAllowList.add(domainEntry)
220 //Log.i("FilterLists", headers.get(1)[0] + " third-party domain initial allow list added: " + domain + " , " + entry + " - " + originalFilterListEntry)
222 // Repeat until all the domains have been processed.
223 } while (domains.contains("|"))
225 } else { // Third-party domain entries.
226 // Process each domain.
228 // Create a string to keep track of the current domain.
231 // Populate the current domain.
232 if (domains.contains("|")) { // There is more than one domain in the list.
233 // Get the first domain from the list.
234 domain = domains.substring(0, domains.indexOf("|"))
236 // Remove the first domain from the list.
237 domains = domains.substring(domains.indexOf("|") + 1)
238 } else { // There is only one domain in the list.
242 // Remove any trailing `*` from the entry.
243 if (entry.endsWith("*")) {
244 entry = entry.substring(0, entry.length - 1)
247 // Process the domain entry.
248 if (entry.contains("*")) { // Process a third-party domain double entry.
249 // Get the index of the wildcard.
250 val wildcardIndex = entry.indexOf("*")
252 // Split the entry into components.
253 val firstEntry = entry.substring(0, wildcardIndex)
254 val secondEntry = entry.substring(wildcardIndex + 1)
256 // Create an entry string array.
257 val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
259 // Add the entry to the allow list.
260 thirdPartyDomainAllowList.add(domainDoubleEntry)
262 //Log.i("FilterLists", headers.get(1)[0] + " third-party domain allow list added: " + domain + " , " + firstEntry + " , " + secondEntry + " - " +
263 // originalFilterListEntry)
264 } else { // Process a third-party domain single entry.
265 // Create an entry string array.
266 val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
268 // Add the entry to the allow list.
269 thirdPartyDomainAllowList.add(domainEntry)
271 //Log.i("FilterLists", headers.get(1)[0] + " third-party domain allow list added: " + domain + " , " + entry + " - " + originalFilterListEntry)
273 // Repeat until all the domains have been processed.
274 } while (domains.contains("|"))
276 } else { // Process third-party allow list entries.
278 val entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
280 // Process the entry.
281 if (entry.contains("*")) { // There are two or more entries.
282 // Get the index of the wildcard.
283 val wildcardIndex = entry.indexOf("*")
285 // Split the entry into components.
286 val firstEntry = entry.substring(0, wildcardIndex)
287 val secondEntry = entry.substring(wildcardIndex + 1)
289 // Process the second entry.
290 if (secondEntry.contains("*")) { // There are three or more entries.
291 // Get the index of the wildcard.
292 val secondWildcardIndex = secondEntry.indexOf("*")
294 // Split the entry into components.
295 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
296 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
298 // Process the third entry.
299 if (thirdEntry.contains("*")) { // There are four or more entries.
300 // Get the index of the wildcard.
301 val thirdWildcardIndex = thirdEntry.indexOf("*")
303 // Split the entry into components.
304 val realThirdEntry = thirdEntry.substring(0, thirdWildcardIndex)
305 val fourthEntry = thirdEntry.substring(thirdWildcardIndex + 1)
307 // Process the fourth entry.
308 if (fourthEntry.contains("*")) { // Process a third-party allow list quintuple entry.
309 // Get the index of the wildcard.
310 val fourthWildcardIndex = fourthEntry.indexOf("*")
312 // Split the entry into components.
313 val realFourthEntry = fourthEntry.substring(0, fourthWildcardIndex)
314 val fifthEntry = fourthEntry.substring(fourthWildcardIndex + 1)
316 // Create an entry string array.
317 val quintupleEntry = arrayOf(firstEntry, realSecondEntry, realThirdEntry, realFourthEntry, fifthEntry, originalFilterListEntry)
319 // Add the entry to the allow list.
320 thirdPartyAllowList.add(quintupleEntry)
322 //Log.i("FilerLists", headers.get(1)[0] + " third-party allow list added: " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " +
323 // realFourthEntry + " , " + fifthEntry + " - " + originalFilterListEntry)
324 } else { // Third-party allow list quadruple entry.
325 // Create an entry string array.
326 val quadrupleEntry = arrayOf(firstEntry, realSecondEntry, realThirdEntry, fourthEntry, originalFilterListEntry)
328 // Add the entry to the allow list.
329 thirdPartyAllowList.add(quadrupleEntry)
331 //Log.i("FilterLists", headers.get(1)[0] + " third-party allow list added: " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " +
332 // fourthEntry + " - " + originalAllowListEntry)
334 } else { // Process a third-party allow list triple entry.
335 // Create an entry string array.
336 val tripleEntry = arrayOf(firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
338 // Add the entry to the allow list.
339 thirdPartyAllowList.add(tripleEntry)
341 //Log.i("AllowLists", headers.get(1)[0] + " third-party allow list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + " - " +
342 // originalFilterListEntry)
344 } else { // Process a third-party allow list double entry.
345 // Create an entry string array.
346 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
348 // Add the entry to the allow list.
349 thirdPartyAllowList.add(doubleEntry)
351 //Log.i("FilterLists", headers.get(1)[0] + " third-party allow list added: " + firstEntry + " , " + secondEntry + " - " + originalFilterListEntry)
353 } else { // Process a third-party allow list single entry.
354 // Create an entry string array.
355 val singleEntry = arrayOf(entry, originalFilterListEntry)
357 // Add the entry to the allow list.
358 thirdPartyAllowList.add(singleEntry)
360 //Log.i("FilterLists", headers.get(1)[0] + " third-party domain allow list added: " + entry + " - " + originalFilterListEntry)
363 } else if (filterListEntry.contains("domain=")) { // Process domain allow list entries.
365 var entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
366 val filters = filterListEntry.substring(filterListEntry.indexOf("$") + 1)
367 var domains = filters.substring(filters.indexOf("domain=") + 7)
369 // Process the entry.
370 if (entry.startsWith("|")) { // Initial domain allow list entries.
371 // Strip the initial `|`.
372 entry = entry.substring(1)
374 // Process the entry.
375 if (entry == "http://" || entry == "https://") { // Ignore generic entries.
376 // Do nothing. These entries are designed for filter options that Privacy Browser does not use.
378 //Log.i("FilterLists", headers.get(1)[0] + " not added: " + originalFilterListEntry)
379 } else { // Initial domain allow list entry.
380 // Process each domain.
382 // Create a string to keep track of the current domain.
385 // Get the first domain.
386 if (domains.contains("|")) { // There is more than one domain in the list.
387 // Get the first domain from the list.
388 domain = domains.substring(0, domains.indexOf("|"))
390 // Remove the first domain from the list.
391 domains = domains.substring(domains.indexOf("|") + 1)
392 } else { // There is only one domain in the list.
396 // Process the entry.
397 if (entry.contains("*")) { // There are two or more entries.
398 // Get the index of the wildcard.
399 val wildcardIndex = entry.indexOf("*")
401 // Split the entry into components.
402 val firstEntry = entry.substring(0, wildcardIndex)
403 val secondEntry = entry.substring(wildcardIndex + 1)
405 // Process the second entry.
406 if (secondEntry.contains("*")) { // Process a domain initial triple entry.
407 // Get the index of the wildcard.
408 val secondWildcardIndex = secondEntry.indexOf("*")
410 // Split the entry into components.
411 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
412 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
414 // Create an entry string array.
415 val domainTripleEntry = arrayOf(domain, firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
417 // Add the entry to the allow list.
418 domainInitialAllowList.add(domainTripleEntry)
420 //Log.i("FilterLists", headers.get(1)[0] + " domain initial allow list entry added: " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " +
421 // thirdEntry + " - " + originalFilterListEntry)
422 } else { // Process a domain initial double entry.
423 // Create an entry string array.
424 val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
426 // Add the entry to the allow list.
427 domainInitialAllowList.add(domainDoubleEntry)
429 //Log.i("FilterLists", headers.get(1)[0] + " domain initial allow list entry added: " + domain + " , " + firstEntry + " , " + secondEntry + " - " +
430 // originalFilterListEntry)
432 } else { // Process a domain initial single entry.
433 // Create an entry string array.
434 val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
436 // Add the entry to the allow list.
437 domainInitialAllowList.add(domainEntry)
439 //Log.i("FilterLists", headers.get(1)[0] + " domain initial allow list entry added: " + domain + " , " + entry + " - " + originalFilterListEntry)
441 // Repeat until all the domains have been processed.
442 } while (domains.contains("|"))
444 } else if (entry.endsWith("|")) { // Final domain allow list entries.
445 // Strip the `|` from the end of the entry.
446 entry = entry.substring(0, entry.length - 1)
448 // Process each domain.
450 // Create a string to keep track of the current domain.
453 // Get the first domain.
454 if (domains.contains("|")) { // There is more than one domain in the list.
455 // Get the first domain from the list.
456 domain = domains.substring(0, domains.indexOf("|"))
458 // Remove the first domain from the list.
459 domains = domains.substring(domains.indexOf("|") + 1)
460 } else { // There is only one domain in the list.
464 if (entry.contains("*")) { // Domain final allow list double entry.
465 // Get the index of the wildcard.
466 val wildcardIndex = entry.indexOf("*")
468 // Split the entry into components.
469 val firstEntry = entry.substring(0, wildcardIndex)
470 val secondEntry = entry.substring(wildcardIndex + 1)
472 // Create an entry string array.
473 val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
475 // Add the entry to the allow list.
476 domainFinalAllowList.add(domainDoubleEntry)
478 //Log.i("FilterLists", headers.get(1)[0] + " domain final allow list added: " + domain + " , " + firstEntry + " , " + secondEntry + " - " +
479 // originalFilterListEntry);
480 } else { // Process a domain final allow list single entry.
481 // create an entry string array.
482 val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
484 // Add the entry to the allow list.
485 domainFinalAllowList.add(domainEntry)
487 //Log.i("FilterLists", headers.get(1)[0] + " domain final allow list added: " + domain + " , " + entry + " - " + originalFilterListEntry);
489 // Repeat until all the domains have been processed.
490 } while (domains.contains("|"))
491 } else { // Standard domain allow list entries with filters.
492 if (domains.contains("~")) { // It is uncertain what a `~` domain means inside an `@@` entry.
495 //Log.i("FilterLists", headers.get(1)[0] + " not added: " + originalFilterListEntry)
497 // Process each domain.
499 // Create a string to keep track of the current domain.
502 // Get the first domain.
503 if (domains.contains("|")) { // There is more than one domain in the list.
504 // Get the first domain from the list.
505 domain = domains.substring(0, domains.indexOf("|"))
507 // Remove the first domain from the list.
508 domains = domains.substring(domains.indexOf("|") + 1)
509 } else { // There is only one domain in the list.
513 // Process the entry.
514 if (entry.contains("*")) { // There are two or more entries.
515 // Get the index of the wildcard.
516 val wildcardIndex = entry.indexOf("*")
518 // Split the entry into components.
519 val firstEntry = entry.substring(0, wildcardIndex)
520 val secondEntry = entry.substring(wildcardIndex + 1)
522 // Process the second entry.
523 if (secondEntry.contains("*")) { // There are three or more entries.
524 // Get the index of the wildcard.
525 val secondWildcardIndex = secondEntry.indexOf("*")
527 // Split the entry into components.
528 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
529 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
531 // Process the third entry.
532 if (thirdEntry.contains("*")) { // Process a domain allow list quadruple entry.
533 // Get the index of the wildcard.
534 val thirdWildcardIndex = thirdEntry.indexOf("*")
536 // Split the entry into components.
537 val realThirdEntry = thirdEntry.substring(0, thirdWildcardIndex)
538 val fourthEntry = thirdEntry.substring(thirdWildcardIndex + 1)
540 // Create an entry string array.
541 val domainQuadrupleEntry = arrayOf(domain, firstEntry, realSecondEntry, realThirdEntry, fourthEntry, originalFilterListEntry)
543 // Add the entry to the allow list.
544 domainAllowList.add(domainQuadrupleEntry)
546 //Log.i("FilterLists", headers.get(1)[0] + " domain allow list added: " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " +
547 // realThirdEntry + " , " + fourthEntry + " - " + originalFilterListEntry)
548 } else { // Process a domain allow list triple entry.
549 // Create an entry string array.
550 val domainTripleEntry = arrayOf(domain, firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
552 // Add the entry to the allow list.
553 domainAllowList.add(domainTripleEntry)
555 //Log.i("FilterLists", headers.get(1)[0] + " domain allow list added: " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " +
556 // thirdEntry + " - " + originalFilterListEntry)
558 } else { // Process a domain allow list double entry.
559 // Create an entry string array.
560 val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
562 // Add the entry to the allow list.
563 domainAllowList.add(domainDoubleEntry)
565 //Log.i("FilterLists", headers.get(1)[0] + " domain allow list added: " + domain + " , " + firstEntry + " , " + secondEntry + " - " originalFilterListEntry)
567 } else { // Process a domain allow list single entry.
568 // Create an entry string array.
569 val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
571 // Add the entry to the allow list.
572 domainAllowList.add(domainEntry)
574 //Log.i("FilterLists", headers.get(1)[0] + " domain allow list added: " + domain + " , " + entry + " - " + originalFilterListEntry)
576 // Repeat until all the domains have been processed.
577 } while (domains.contains("|"))
580 } // Ignore all other filter entries.
581 } else if (filterListEntry.endsWith("|")) { // Final allow list entries.
582 // Remove the final `|` from the entry.
583 val entry = filterListEntry.substring(0, filterListEntry.length - 1)
585 // Process the entry.
586 if (entry.contains("*")) { // Process a final allow list double entry
587 // Get the index of the wildcard.
588 val wildcardIndex = entry.indexOf("*")
590 // split the entry into components.
591 val firstEntry = entry.substring(0, wildcardIndex)
592 val secondEntry = entry.substring(wildcardIndex + 1)
594 // Create an entry string array.
595 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
597 // Add the entry to the allow list.
598 finalAllowList.add(doubleEntry)
600 //Log.i("FilterLists", headers.get(1)[0] + " final allow list added: " + firstEntry + " , " + secondEntry + " - " + originalFilterListEntry)
601 } else { // Process a final allow list single entry.
602 // Create an entry string array.
603 val singleEntry = arrayOf(entry, originalFilterListEntry)
605 // Add the entry to the allow list.
606 finalAllowList.add(singleEntry)
608 //Log.i("FilterLists", headers.get(1)[0] + " final allow list added: " + entry + " - " + originalFilterListEntry)
610 } else { // Main allow list entries.
611 // Process the entry.
612 if (filterListEntry.contains("*")) { // There are two or more entries.
613 // Get the index of the wildcard.
614 val wildcardIndex = filterListEntry.indexOf("*")
616 // Split the entry into components.
617 val firstEntry = filterListEntry.substring(0, wildcardIndex)
618 val secondEntry = filterListEntry.substring(wildcardIndex + 1)
620 // Process the second entry.
621 if (secondEntry.contains("*")) { // Main allow list triple entry.
622 // Get the index of the wildcard.
623 val secondWildcardIndex = secondEntry.indexOf("*")
625 // Split the entry into components.
626 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
627 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
629 // Create an entry string array.
630 val tripleEntry = arrayOf(firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
632 // Add the entry to the allow list.
633 mainAllowList.add(tripleEntry)
635 //Log.i("FilterLists", headers.get(1)[0] + " main allow list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + " - " + originalFilterListEntry)
636 } else { // Process a main allow list double entry.
637 // Create an entry string array.
638 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
640 // Add the entry to the allow list.
641 mainAllowList.add(doubleEntry)
643 //Log.i("FilterLists", headers.get(1)[0] + " main allow list added: " + firstEntry + " , " + secondEntry + " - " + originalFilterListEntry)
645 } else { // Process a main allow list single entry.
646 // Create an entry string array.
647 val singleEntry = arrayOf(filterListEntry, originalFilterListEntry)
649 // Add the entry to the allow list.
650 mainAllowList.add(singleEntry)
652 //Log.i("FilterLists", headers.get(1)[0] + " main allow list added: " + filterListEntry + " - " + originalFilterListEntry)
655 } else if (filterListEntry.endsWith("|")) { // Final block list entries.
656 // Strip out the final "|"
657 var entry = filterListEntry.substring(0, filterListEntry.length - 1)
659 // Strip out any initial `||`. They are redundant in this case because the block list entry is being matched against the end of the URL.
660 if (entry.startsWith("||"))
661 entry = entry.substring(2)
663 // Process the entry.
664 if (entry.contains("*")) { // Process a final block list double entry.
665 // Get the index of the wildcard.
666 val wildcardIndex = entry.indexOf("*")
668 // Split the entry into components.
669 val firstEntry = entry.substring(0, wildcardIndex)
670 val secondEntry = entry.substring(wildcardIndex + 1)
672 // Create an entry string array.
673 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
675 // Add the entry to the block list.
676 finalBlockList.add(doubleEntry)
678 //Log.i("FilterLists", headers.get(1)[0] + " final block list added: " + firstEntry + " , " + secondEntry + " - " + originalFilterListEntry)
679 } else { // Process a final block list single entry.
680 // Create an entry string array.
681 val singleEntry = arrayOf(entry, originalFilterListEntry)
683 // Add the entry to the block list.
684 finalBlockList.add(singleEntry)
686 //Log.i("FilterLists", headers.get(1)[0] + " final block list added: " + entry + " - " + originalFilterListEntry)
688 } else if (filterListEntry.contains("$")) { // Entries with filter options.
689 // Strip out any initial `||`. These will be treated like any other entry.
690 if (filterListEntry.startsWith("||"))
691 filterListEntry = filterListEntry.substring(2)
693 // Process the entry.
694 if (filterListEntry.contains("third-party")) { // Third-party entries.
695 // Process the entry.
696 if (filterListEntry.contains("~third-party")) { // Third-party filter allow list entries.
697 // Do not process these allow list entries. They are designed to combine with block filters that Privacy Browser doesn't use, like `subdocument` and `xmlhttprequest`.
699 //Log.i("FilterLists", headers.get(1)[0] + " not added: " + originalFilterListEntry)
700 } else if (filterListEntry.contains("domain=")) { // Third-party domain entries.
701 // Process the domain entry.
702 if (filterListEntry.startsWith("|")) { // Third-party domain initial entries.
703 // Strip the initial `|`.
704 filterListEntry = filterListEntry.substring(1)
707 val entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
708 val filters = filterListEntry.substring(filterListEntry.indexOf("$") + 1)
709 var domains = filters.substring(filters.indexOf("domain=") + 7)
711 // Process the entry.
712 if (entry == "http:" || entry == "https:" || entry == "http://" || entry == "https://") { // Ignore generic entries.
713 // Do nothing. These entries will almost entirely disable the website.
714 // Often the original entry blocks filter options like `$script`, which Privacy Browser does not differentiate.
716 //Log.i("FilterLists", headers.get(1)[0] + " not added: " + originalFilterListEntry)
717 } else { // Third-party domain initial entries.
718 // Process each domain.
720 // Create a string to keep track of the current domain.
723 // Get the first domain.
724 if (domains.contains("|")) { // There is more than one domain in the list.
725 // Get the first domain from the list.
726 domain = domains.substring(0, domains.indexOf("|"))
728 // Remove the first domain from the list.
729 domains = domains.substring(domains.indexOf("|") + 1)
730 } else { // There is only one domain in the list.
734 // Process the entry.
735 if (entry.contains("*")) { // Three are two or more entries.
736 // Get the index of the wildcard.
737 val wildcardIndex = entry.indexOf("*")
739 // Split the entry into components.
740 val firstEntry = entry.substring(0, wildcardIndex)
741 val secondEntry = entry.substring(wildcardIndex + 1)
743 // Process the second entry.
744 if (secondEntry.contains("*")) { // Third-party domain initial block list triple entry.
745 // Get the index of the wildcard.
746 val secondWildcardIndex = secondEntry.indexOf("*")
748 // Split the entry into components.
749 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
750 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
752 // Create an entry string array.
753 val tripleDomainEntry = arrayOf(domain, firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
755 // Add the entry to the block list.
756 thirdPartyDomainInitialBlockList.add(tripleDomainEntry)
758 //Log.i("FilterLists", headers.get(1)[0] + " third-party domain initial block list added: " + domain + " , " + firstEntry + " , " + realSecondEntry +
759 // " , " + thirdEntry + " - " + originalFilterListEntry)
760 } else { // Process a third-party domain initial block list double entry.
761 // Create an entry string array.
762 val doubleDomainEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
764 // Add the entry to the block list.
765 thirdPartyDomainInitialBlockList.add(doubleDomainEntry)
767 //Log.i("FilterLists", headers.get(1)[0] + " third-party domain initial block list added: " + domain + " , " + firstEntry + " , " + secondEntry +
768 // " - " + originalFilterListEntry)
770 } else { // Process a third-party domain initial block list single entry.
771 // Create an entry string array.
772 val singleEntry = arrayOf(domain, entry, originalFilterListEntry)
774 // Add the entry to the block list.
775 thirdPartyDomainInitialBlockList.add(singleEntry)
777 //Log.i("FilterLists", headers.get(1)[0] + " third-party domain initial block list added: " + domain + " , " + entry + " - " + originalFilterListEntry)
779 // Repeat until all the domains have been processed.
780 } while (domains.contains("|"))
782 } else if (filterListEntry.contains("\\")) { // Process a third-party domain block list regular expression.
783 // Parse the entry. At least one regular expression in this entry contains `$`, so the parser uses `/$`.
784 val entry = filterListEntry.substring(0, filterListEntry.indexOf("/$") + 1)
785 val filters = filterListEntry.substring(filterListEntry.indexOf("/$") + 2)
786 var domains = filters.substring(filters.indexOf("domain=") + 7)
788 // Process each domain.
790 // Create a string to keep track of the current domain.
793 // Get the first domain.
794 if (domains.contains("|")) { // There is more than one domain in the list.
795 // Get the first domain from the list.
796 domain = domains.substring(0, domains.indexOf("|"))
798 // Remove the first domain from the list.
799 domains = domains.substring(domains.indexOf("|") + 1)
800 } else { // There is only one domain in the list.
804 // Create an entry string array.
805 val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
807 // Add the entry to the block list.
808 thirdPartyDomainRegularExpressionBlockList.add(domainEntry)
810 //Log.i("FilterLists", headers.get(1)[0] + " third-party domain regular expression block list added: " + domain + " , " + entry + " - " + originalFilterListEntry)
811 // Repeat until all the domains have been processed.
812 } while (domains.contains("|"))
813 } else { // Third-party domain entries.
815 var entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
816 val filters = filterListEntry.substring(filterListEntry.indexOf("$") + 1)
817 var domains = filters.substring(filters.indexOf("domain=") + 7)
819 // Strip any trailing "*" from the entry.
820 if (entry.endsWith("*"))
821 entry = entry.substring(0, entry.length - 1)
823 // Create an allow domain tracker.
824 var allowDomain = false
826 // Process each domain.
828 // Create a string to keep track of the current domain.
831 // Get the first domain.
832 if (domains.contains("|")) { // There is more than one domain in the list.
833 // Get the first domain from the list.
834 domain = domains.substring(0, domains.indexOf("|"))
836 // Remove the first domain from the list.
837 domains = domains.substring(domains.indexOf("|") + 1)
838 } else { // The is only one domain in the list.
842 // Differentiate between block list domains and allow list domains.
843 if (domain.startsWith("~")) { // Allow list third-party domain entry.
844 // Strip the initial `~`.
845 domain = domain.substring(1)
847 // Set the allow list domain flag.
850 // Process the entry.
851 if (entry.contains("*")) { // Third-party domain allow list double entry.
852 // Get the index of the wildcard.
853 val wildcardIndex = entry.indexOf("*")
855 // Split the entry into components.
856 val firstEntry = entry.substring(0, wildcardIndex)
857 val secondEntry = entry.substring(wildcardIndex + 1)
859 // Create an entry string array.
860 val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
862 // Add the entry to the allow list.
863 thirdPartyDomainAllowList.add(domainDoubleEntry)
865 //Log.i("FilterLists", headers.get(1)[0] + " third-party domain allow list added: " + domain + " , " + firstEntry + " , " + secondEntry + " - " +
866 // originalFilterListEntry)
867 } else { // Process a third-party domain allow list single entry.
868 // Create an entry string array.
869 val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
871 // Add the entry to the allow list.
872 thirdPartyDomainAllowList.add(domainEntry)
874 //Log.i("FilterLists", headers.get(1)[0] + " third-party domain allow list added: " + domain + " , " + entry + " - " + originalFilterListEntry)
876 } else { // Third-party domain block list entries.
877 if (entry.contains("*")) { // Process a third-party domain block list double entry.
878 // Get the index of the wildcard.
879 val wildcardIndex = entry.indexOf("*")
881 // Split the entry into components.
882 val firstEntry = entry.substring(0, wildcardIndex)
883 val secondEntry = entry.substring(wildcardIndex + 1)
885 // Create an entry string array.
886 val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
888 // Add the entry to the block list
889 thirdPartyDomainBlockList.add(domainDoubleEntry)
891 //Log.i("FilterLists", headers.get(1)[0] + " third-party domain block list added: " + domain + " , " + firstEntry + " , " + secondEntry + " - " +
892 // originalFilterListEntry)
893 } else { // Process a third-party domain block list single entry.
894 // Create an entry string array.
895 val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
897 // Add the entry to the block list.
898 thirdPartyDomainBlockList.add(domainEntry)
900 //Log.i("FilterLists", headers.get(1)[0] + " third-party domain block list added: " + domain + " , " + entry + " - " + originalFilterListEntry)
903 // Repeat until all the domains have been processed.
904 } while (domains.contains("|"))
906 // Add a third-party block list entry if an allow list domain was processed.
908 if (entry.contains("*")) { // Third-party block list double entry.
909 // Get the index of the wildcard.
910 val wildcardIndex = entry.indexOf("*")
912 // Split the entry into components.
913 val firstEntry = entry.substring(0, wildcardIndex)
914 val secondEntry = entry.substring(wildcardIndex + 1)
916 // Create an entry string array.
917 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
919 // Add the entry to the block list.
920 thirdPartyBlockList.add(doubleEntry)
922 //Log.i("FilterLists", headers.get(1)[0] + " third-party block list added: " + firstEntry + " , " + secondEntry + " - " + originalFilterListEntry)
923 } else { // Process a third-party block list single entry.
924 // Create an entry string array.
925 val singleEntry = arrayOf(entry, originalFilterListEntry)
927 // Add an entry to the block list.
928 thirdPartyBlockList.add(singleEntry)
930 //Log.i("FilterLists", headers.get(1)[0] + " third-party block list added: " + entry + " - " + originalFilterListEntry)
934 } else if (filterListEntry.startsWith("|")) { // Third-party initial block list entries.
935 // Strip the initial `|`.
936 filterListEntry = filterListEntry.substring(1)
939 val entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
941 // Process the entry.
942 if (entry.contains("*")) { // Process a third-party initial block list double entry.
943 // Get the index of the wildcard.
944 val wildcardIndex = entry.indexOf("*")
946 // Split the entry into components.
947 val firstEntry = entry.substring(0, wildcardIndex)
948 val secondEntry = entry.substring(wildcardIndex + 1)
950 // Create an entry string array.
951 val thirdPartyDoubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
953 // Add the entry to the block list.
954 thirdPartyInitialBlockList.add(thirdPartyDoubleEntry)
956 //Log.i("FilterLists", headers.get(1)[0] + " third-party initial block list added: " + firstEntry + " , " + secondEntry + " - " + originalFilterListEntry)
957 } else { // Process a third-party initial block list single entry.
958 // Create an entry string array.
959 val singleEntry = arrayOf(entry, originalFilterListEntry)
961 // Add the entry to the block list.
962 thirdPartyInitialBlockList.add(singleEntry)
964 //Log.i("FilterLists", headers.get(1)[0] + " third-party initial block list added: " + entry + " - " + originalFilterListEntry)
966 } else if (filterListEntry.contains("\\")) { // Third-party regular expression block list entry.
968 val entry = if (filterListEntry.contains("$/$")) // The first `$` is part of the regular expression.
969 filterListEntry.substring(0, filterListEntry.indexOf("$/$") + 2)
970 else // The only `$` indicates the filter options.
971 filterListEntry.substring(0, filterListEntry.indexOf("$"))
973 // Create an entry string array.
974 val singleEntry = arrayOf(entry, originalFilterListEntry)
976 // Add the entry to the block list.
977 thirdPartyRegularExpressionBlockList.add(singleEntry)
979 //Log.i("FilterLists", headers.get(1)[0] + " third-party regular expression block list added: " + entry + " - " + originalFilterListEntry)
980 } else if (filterListEntry.contains("*")) { // Third-party and regular expression block list entries.
982 var entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
984 // Process the entry.
985 if (entry.endsWith("*")) { // Third-party block list single entry.
986 // Strip the final `*`.
987 entry = entry.substring(0, entry.length - 1)
989 // Create an entry string array.
990 val singleEntry = arrayOf(entry, originalFilterListEntry)
992 // Add the entry to the block list.
993 thirdPartyBlockList.add(singleEntry)
995 //Log.i("FilterLists", headers.get(1)[0] + " third party block list added: " + entry + " - " + originalFilterListEntry)
996 } else { // There are two or more entries.
997 // Get the index of the wildcard.
998 val wildcardIndex = entry.indexOf("*")
1000 // Split the entry into components.
1001 val firstEntry = entry.substring(0, wildcardIndex)
1002 val secondEntry = entry.substring(wildcardIndex + 1)
1004 // Process the second entry.
1005 if (secondEntry.contains("*")) { // There are three or more entries.
1006 // Get the index of the wildcard.
1007 val secondWildcardIndex = secondEntry.indexOf("*")
1009 // Split the entry into components.
1010 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
1011 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
1013 // Process a third entry.
1014 if (thirdEntry.contains("*")) { // Third-party block list quadruple entry.
1015 // Get the index of the wildcard.
1016 val thirdWildcardIndex = thirdEntry.indexOf("*")
1018 // Split the entry into components.
1019 val realThirdEntry = thirdEntry.substring(0, thirdWildcardIndex)
1020 val fourthEntry = thirdEntry.substring(thirdWildcardIndex + 1)
1022 // Create an entry string array.
1023 val quadrupleEntry = arrayOf(firstEntry, realSecondEntry, realThirdEntry, fourthEntry, originalFilterListEntry)
1025 // Add the entry to the block list.
1026 thirdPartyBlockList.add(quadrupleEntry)
1028 //Log.i("FilterLists", headers.get(1)[0] + " third-party block list added: " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " +
1029 // fourthEntry + " - " + originalFilterListEntry);
1030 } else { // Third-party block list triple entry.
1031 // Create an entry string array.
1032 val tripleEntry = arrayOf(firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
1034 // Add the entry to the block list.
1035 thirdPartyBlockList.add(tripleEntry)
1037 //Log.i("FilterLists", headers.get(1)[0] + " third-party block list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + " - " +
1038 // originalFilterListEntry)
1040 } else { // Third-party block list double entry.
1041 // Create an entry string array.
1042 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
1044 // Add the entry to the block list.
1045 thirdPartyBlockList.add(doubleEntry)
1047 //Log.i("FilterLists", headers.get(1)[0] + " third-party block list added: " + firstEntry + " , " + secondEntry + " - " + originalFilterListEntry)
1050 } else { // Third party block list single entry.
1052 val entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
1054 // Create an entry string array.
1055 val singleEntry = arrayOf(entry, originalFilterListEntry)
1057 // Add the entry to the block list.
1058 thirdPartyBlockList.add(singleEntry)
1060 //Log.i("FilterLists", headers.get(1)[0] + " third party block list added: " + entry + " - " + originalFilterListEntry)
1062 } else if (filterListEntry.substring(filterListEntry.indexOf("$")).contains("domain=")) { // Domain entries.
1063 // Process the entry.
1064 if (filterListEntry.contains("~")) { // Domain allow list entries.
1065 // Separate the filters.
1066 var entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
1067 val filters = filterListEntry.substring(filterListEntry.indexOf("$") + 1)
1068 var domains = filters.substring(filters.indexOf("domain=") + 7)
1070 // Strip any final `*` from the entry. They are redundant.
1071 if (entry.endsWith("*"))
1072 entry = entry.substring(0, entry.length - 1)
1074 // Process each domain.
1076 // Create a string to keep track of the current domain.
1079 // Get the first domain.
1080 if (domains.contains("|")) { // There is more than one domain in the list.
1081 // Get the first domain from the list.
1082 domain = domains.substring(0, domains.indexOf("|"))
1084 // Remove the first domain from the list.
1085 domains = domains.substring(domains.indexOf("|") + 1)
1086 } else { // There is only one domain in the list.
1090 // Strip the initial `~`.
1091 domain = domain.substring(1)
1093 // Process the entry.
1094 if (entry.contains("*")) { // There are two or more entries.
1095 // Get the index of the wildcard.
1096 val wildcardIndex = entry.indexOf("*")
1098 // Split the entry into components.
1099 val firstEntry = entry.substring(0, wildcardIndex)
1100 val secondEntry = entry.substring(wildcardIndex + 1)
1102 // Process the second entry.
1103 if (secondEntry.contains("*")) { // Domain allow list triple entry.
1104 // Get the index of the wildcard.
1105 val secondWildcardIndex = secondEntry.indexOf("*")
1107 // Split the entry into components.
1108 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
1109 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
1111 // Create an entry string array.
1112 val domainTripleEntry = arrayOf(domain, firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
1114 // Add the entry to the allow list.
1115 domainAllowList.add(domainTripleEntry)
1117 //Log.i("FilterLists", headers.get(1)[0] + " domain allow list added: " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry +
1118 // " - " + originalFilterListEntry)
1119 } else { // Process a domain allow list double entry.
1120 // Create an entry string array.
1121 val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
1123 // Add the entry to the allow list.
1124 domainAllowList.add(domainDoubleEntry)
1126 //Log.i("FilterLists", headers.get(1)[0] + " domain allow list added: " + domain + " , " + firstEntry + " , " + secondEntry + " - " + originalFilterListEntry)
1128 } else { // Process a domain allow list single entry.
1129 // Create an entry string array.
1130 val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
1132 // Add the entry to the allow list.
1133 domainAllowList.add(domainEntry)
1135 //Log.i("FilterLists", headers.get(1)[0] + " domain allow list added: " + domain + " , " + entry + " - " + originalFilterListEntry)
1137 // Repeat until all the domains have been processed.
1138 } while (domains.contains("|"))
1139 } else { // Domain block list entries.
1140 // Separate the filters.
1141 var entry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
1142 val filters = filterListEntry.substring(filterListEntry.indexOf("$") + 1)
1143 var domains = filters.substring(filters.indexOf("domain=") + 7)
1145 // Only process the item if the entry is not empty. For example, some lines begin with `$websocket`, which create an empty entry.
1146 if (entry.isNotEmpty()) {
1147 // Process each domain.
1149 // Create a string to keep track of the current domain.
1152 // Get the first domain.
1153 if (domains.contains("|")) { // There is more than one domain in the list.
1154 // Get the first domain from the list.
1155 domain = domains.substring(0, domains.indexOf("|"))
1157 // Remove the first domain from the list.
1158 domains = domains.substring(domains.indexOf("|") + 1)
1159 } else { // There is only one domain in the list.
1163 // Process the entry.
1164 if (entry.startsWith("|")) { // Domain initial block list entries.
1165 // Remove the initial `|`;
1166 entry = entry.substring(1)
1168 // Process the entry.
1169 if (entry == "http://" || entry == "https://") {
1170 // Do nothing. These entries will entirely block the website.
1171 // Often the original entry blocks `$script` but Privacy Browser does not currently differentiate between scripts and other entries.
1173 //Log.i("FilterLists", headers.get(1)[0] + " not added: " + originalFilterListEntry)
1174 } else { // Domain initial block list entry.
1175 // Create an entry string array.
1176 val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
1178 // Add the entry to the block list.
1179 domainInitialBlockList.add(domainEntry)
1181 //Log.i("FilterLists", headers.get(1)[0] + " domain initial block list added: " + domain + " , " + entryBase + " - " + originalFilterListEntry)
1183 } else if (entry.endsWith("|")) { // Domain final block list entries.
1184 // Remove the final `|`.
1185 entry = entry.substring(0, entry.length - 1)
1187 // Process the entry.
1188 if (entry.contains("*")) { // Process a domain final block list double entry.
1189 // Get the index of the wildcard.
1190 val wildcardIndex = entry.indexOf("*")
1192 // Split the entry into components.
1193 val firstEntry = entry.substring(0, wildcardIndex)
1194 val secondEntry = entry.substring(wildcardIndex + 1)
1196 // Create an entry string array.
1197 val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
1199 // Add the entry to the block list.
1200 domainFinalBlockList.add(domainDoubleEntry)
1202 //Log.i("FilterLists", headers.get(1)[0] + " domain final block list added: " + domain + " , " + firstEntry + " , " + secondEntry + " - " +
1203 // originalFilterListEntry)
1204 } else { // Domain final block list single entry.
1205 // Create an entry string array.
1206 val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
1208 // Add the entry to the block list.
1209 domainFinalBlockList.add(domainEntry)
1211 //Log.i("FilterLists", headers.get(1)[0] + " domain final block list added: " + domain + " , " + entryBase + " - " + originalFilterListEntry)
1213 } else if (entry.contains("\\")) { // Domain regular expression block list entry.
1214 // Create an entry string array.
1215 val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
1217 // Add the entry to the block list.
1218 domainRegularExpressionBlockList.add(domainEntry)
1220 //Log.i("FilterLists", headers.get(1)[0] + " domain regular expression block list added: " + domain + " , " + entry + " - " + originalFilterListEntry)
1221 } else if (entry.contains("*")) { // There are two or more entries.
1222 // Get the index of the wildcard.
1223 val wildcardIndex = entry.indexOf("*")
1225 // Split the entry into components.
1226 val firstEntry = entry.substring(0, wildcardIndex)
1227 val secondEntry = entry.substring(wildcardIndex + 1)
1229 // Process the second entry.
1230 if (secondEntry.contains("*")) { // Process a domain block list triple entry.
1231 // Get the index of the wildcard.
1232 val secondWildcardIndex = secondEntry.indexOf("*")
1234 // Split the entry into components.
1235 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
1236 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
1238 // Create an entry string array.
1239 val domainTripleEntry = arrayOf(domain, firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
1241 // Add the entry to the block list.
1242 domainBlockList.add(domainTripleEntry)
1244 //Log.i("FilterLists", headers.get(1)[0] + " domain block list added: " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry +
1245 // " - " + originalFilterListEntry)
1246 } else { // Process a domain block list double entry.
1247 // Create an entry string array.
1248 val domainDoubleEntry = arrayOf(domain, firstEntry, secondEntry, originalFilterListEntry)
1250 // Add the entry to the block list.
1251 domainBlockList.add(domainDoubleEntry)
1253 //Log.i("FilterLists", headers.get(1)[0] + " domain block list added: " + domain + " , " + firstEntry + " , " + secondEntry + " - " +
1254 // originalFilterListEntry)
1256 } else { // Process a domain block list single entry.
1257 // Create an entry string array.
1258 val domainEntry = arrayOf(domain, entry, originalFilterListEntry)
1260 // Add the entry to the block list.
1261 domainBlockList.add(domainEntry)
1263 //Log.i("FilterLists", headers.get(1)[0] + " domain block list added: " + domain + " , " + entry + " - " + originalFilterListEntry)
1265 // Repeat until all the domains have been processed.
1266 } while (domains.contains("|"))
1269 } else if (filterListEntry.contains("~")) { // Allow list entries. Privacy Browser does not differentiate against these filter options, so they are just generally allowed.
1270 // Remove the filter options.
1271 filterListEntry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
1273 // Strip any trailing `*`.
1274 if (filterListEntry.endsWith("*"))
1275 filterListEntry = filterListEntry.substring(0, filterListEntry.length - 1)
1277 // Process the entry.
1278 if (filterListEntry.contains("*")) { // Allow list double entry.
1279 // Get the index of the wildcard.
1280 val wildcardIndex = filterListEntry.indexOf("*")
1282 // Split the entry into components.
1283 val firstEntry = filterListEntry.substring(0, wildcardIndex)
1284 val secondEntry = filterListEntry.substring(wildcardIndex + 1)
1286 // Create an entry string array.
1287 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
1289 // Add the entry to the allow list.
1290 mainAllowList.add(doubleEntry)
1292 //Log.i("FilterLists", headers.get(1)[0] + " main allow list added: " + firstEntry + " , " + secondEntry + " - " + originalFilterListEntry)
1293 } else { // Allow list single entry.
1294 // Create an entry string array.
1295 val singleEntry = arrayOf(filterListEntry, originalFilterListEntry)
1297 // Add the entry to the allow list.
1298 mainAllowList.add(singleEntry)
1300 //Log.i("FilterLists", headers.get(1)[0] + " main allow list added: " + filterListEntry + " - + " + originalFilterListEntry)
1302 } else if (filterListEntry.contains("\\")) { // Regular expression block list entry.
1303 // Remove the filter options.
1304 filterListEntry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
1306 // Create an entry string array.
1307 val singleEntry = arrayOf(filterListEntry, originalFilterListEntry)
1309 // Add the entry to the block list.
1310 regularExpressionBlockList.add(singleEntry)
1312 //Log.i("FilterLists", headers.get(1)[0] + " regular expression block list added: " + filterListEntry + " - " + originalFilterListEntry);
1313 } else { // Block list entries.
1314 // Remove the filter options.
1315 if (!filterListEntry.contains("\$file")) // EasyPrivacy contains an entry with `$file` that does not have filter options.
1316 filterListEntry = filterListEntry.substring(0, filterListEntry.indexOf("$"))
1318 // Strip any trailing `*`. These are redundant.
1319 if (filterListEntry.endsWith("*"))
1320 filterListEntry = filterListEntry.substring(0, filterListEntry.length - 1)
1322 // Process the entry.
1323 if (filterListEntry.startsWith("|")) { // Initial block list entries.
1324 // Strip the initial `|`.
1325 val entry = filterListEntry.substring(1)
1327 if (entry.contains("*")) { // Process an initial block list double entry.
1328 // Get the index of the wildcard.
1329 val wildcardIndex = entry.indexOf("*")
1331 // Split the entry into components.
1332 val firstEntry = entry.substring(0, wildcardIndex)
1333 val secondEntry = entry.substring(wildcardIndex + 1)
1335 // Create an entry string array.
1336 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
1338 // Add the entry to the block list.
1339 initialBlockList.add(doubleEntry)
1341 //Log.i("FilterLists", headers.get(1)[0] + " initial block list added: " + firstEntry + " , " + secondEntry + " - " + originalFilterListEntry)
1342 } else { // Initial blocklist single entry.
1343 // Create an entry string array.
1344 val singleEntry = arrayOf(entry, originalFilterListEntry)
1346 // Add the entry to the block list.
1347 initialBlockList.add(singleEntry)
1349 //Log.i("FilterLists", headers.get(1)[0] + " initial block list added: " + entry + " - " + originalFilterListEntry)
1351 } else if (filterListEntry.endsWith("|")) { // Final block list entries.
1352 // Ignore entries with `object` filters. They can block entire websites and don't have any meaning in the context of Privacy Browser.
1353 if (!originalFilterListEntry.contains("\$object")) {
1354 // Strip the final `|`.
1355 val entry = filterListEntry.substring(0, filterListEntry.length - 1)
1357 // Process the entry.
1358 if (entry.contains("*")) { // There are two or more entries.
1359 // Get the index of the wildcard.
1360 val wildcardIndex = entry.indexOf("*")
1362 // Split the entry into components.
1363 val firstEntry = entry.substring(0, wildcardIndex)
1364 val secondEntry = entry.substring(wildcardIndex + 1)
1366 // Process the second entry.
1367 if (secondEntry.contains("*")) { // Final block list triple entry.
1368 // Get the index of the wildcard.
1369 val secondWildcardIndex = secondEntry.indexOf("*")
1371 // Split the entry into components.
1372 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
1373 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
1375 // Create an entry string array.
1376 val tripleEntry = arrayOf(firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
1378 // Add the entry to the block list.
1379 finalBlockList.add(tripleEntry)
1381 //Log.i("FilterLists", headers.get(1)[0] + " final block list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + " - " + originalFilterListEntry)
1382 } else { // Final block list double entry.
1383 // Create an entry string array.
1384 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
1386 // Add the entry to the block list.
1387 finalBlockList.add(doubleEntry)
1389 //Log.i("FilterLists", headers.get(1)[0] + " final block list added: " + firstEntry + " , " + secondEntry + " - " + originalFilterListEntry)
1391 } else { // Final block list single entry.
1392 // Create an entry sting array.
1393 val singleEntry = arrayOf(entry, originalFilterListEntry)
1395 // Add the entry to the block list.
1396 finalBlockList.add(singleEntry)
1398 //Log.i("FilterLists", headers.get(1)[0] + " final block list added: " + entry + " - " + originalFilterListEntry)
1401 } else if (filterListEntry.contains("*")) { // There are two or more entries.
1402 // Get the index of the wildcard.
1403 val wildcardIndex = filterListEntry.indexOf("*")
1405 // Split the entry into components.
1406 val firstEntry = filterListEntry.substring(0, wildcardIndex)
1407 val secondEntry = filterListEntry.substring(wildcardIndex + 1)
1409 // Process the second entry.
1410 if (secondEntry.contains("*")) { // Main block list triple entry.
1411 // Get the index of the wildcard.
1412 val secondWildcardIndex = secondEntry.indexOf("*")
1414 // Split the entry into components.
1415 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
1416 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
1418 // Create an entry string array.
1419 val tripleEntry = arrayOf(firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
1421 // Add the entry to the block list.
1422 mainBlockList.add(tripleEntry)
1424 //Log.i("FilterLists", headers.get(1)[0] + " main block list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + " - " + originalFilterListEntry)
1425 } else { // Main block list double entry.
1426 // Create an entry string array.
1427 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
1429 // Add the entry to the block list.
1430 mainBlockList.add(doubleEntry)
1432 //Log.i("FilterLists", headers.get(1)[0] + " main block list added: " + firstEntry + " , " + secondEntry + " - " + originalFilterListEntry)
1434 } else if (filterListEntry.isNotBlank()){ // Main block list single entry.
1435 // Create an entry string array.
1436 val singleEntry = arrayOf(filterListEntry, originalFilterListEntry)
1438 // Add the entry to the block list.
1439 mainBlockList.add(singleEntry)
1441 //Log.i("FilterLists", headers.get(1)[0] + " main block list added: " + filterListEntry + " - " + originalFilterListEntry)
1442 } else { // The entry is blank (empty or all white spaces).
1445 //Log.i("FilterLists", "${headers[1][0]} not added: $filterListEntry, $originalFilterListEntry")
1448 } else { // Main block list entries.
1449 // Strip out any initial `||`. These will be treated like any other entry.
1450 if (filterListEntry.startsWith("||"))
1451 filterListEntry = filterListEntry.substring(2)
1453 // Strip out any initial `*`.
1454 if (filterListEntry.startsWith("*"))
1455 filterListEntry = filterListEntry.substring(1)
1457 // Strip out any trailing `*`.
1458 if (filterListEntry.endsWith("*"))
1459 filterListEntry = filterListEntry.substring(0, filterListEntry.length - 1)
1461 // Process the entry.
1462 if (filterListEntry.startsWith("|")) { // Initial block list entries.
1463 // Strip the initial `|`.
1464 val entry = filterListEntry.substring(1)
1466 // Process the entry.
1467 if (entry.contains("*")) { // Initial block list double entry.
1468 // Get the index of the wildcard.
1469 val wildcardIndex = entry.indexOf("*")
1471 // Split the entry into components.
1472 val firstEntry = entry.substring(0, wildcardIndex)
1473 val secondEntry = entry.substring(wildcardIndex + 1)
1475 // Create an entry string array.
1476 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
1478 // Add the entry to the block list.
1479 initialBlockList.add(doubleEntry)
1481 //Log.i("FilterLists", headers.get(1)[0] + " initial block list added: " + firstEntry + " , " + secondEntry + " - " + originalFilterListEntry)
1482 } else { // Initial block list single entry.
1483 // Create an entry string array.
1484 val singleEntry = arrayOf(entry, originalFilterListEntry)
1486 // Add the entry to the block list.
1487 initialBlockList.add(singleEntry)
1489 //Log.i("FilterLists", headers.get(1)[0] + " initial block list added: " + entry + " - " + originalFilterListEntry)
1491 } else if (filterListEntry.endsWith("|")) { // Final block list entries.
1492 // Strip the final `|`.
1493 val entry = filterListEntry.substring(0, filterListEntry.length - 1)
1495 // Process the entry.
1496 if (entry.contains("*")) { // There are two or more entries.
1497 // Get the index of the wildcard.
1498 val wildcardIndex = entry.indexOf("*")
1500 // Split the entry into components.
1501 val firstEntry = entry.substring(0, wildcardIndex)
1502 val secondEntry = entry.substring(wildcardIndex + 1)
1504 // Process the second entry.
1505 if (secondEntry.contains("*")) { // Final block list triple entry.
1506 // Get the index of the wildcard.
1507 val secondWildcardIndex = secondEntry.indexOf("*")
1509 // Split the entry into components.
1510 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
1511 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
1513 // Create an entry string array.
1514 val tripleEntry = arrayOf(firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
1516 // Add the entry to the block list.
1517 finalBlockList.add(tripleEntry)
1519 //Log.i("FilterLists", headers.get(1)[0] + " final block list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + " - " + originalFilterListEntry)
1520 } else { // Final block list double entry.
1521 // Create an entry string array.
1522 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
1524 // Add the entry to the block list.
1525 finalBlockList.add(doubleEntry)
1527 //Log.i("FilterLists", headers.get(1)[0] + " final block list added: " + firstEntry + " , " + secondEntry + " - " + originalFilterListEntry)
1529 } else { // Final block list single entry.
1530 // Create an entry string array.
1531 val singleEntry = arrayOf(entry, originalFilterListEntry)
1533 // Add the entry to the block list.
1534 finalBlockList.add(singleEntry)
1536 //Log.i("FilterLists", headers.get(1)[0] + " final block list added: " + entry + " - " + originalFilterListEntry)
1538 } else { // Main block list entries.
1539 if (filterListEntry.contains("*")) { // There are two or more entries.
1540 // Get the index of the wildcard.
1541 val wildcardIndex = filterListEntry.indexOf("*")
1543 // Split the entry into components.
1544 val firstEntry = filterListEntry.substring(0, wildcardIndex)
1545 val secondEntry = filterListEntry.substring(wildcardIndex + 1)
1547 // Process the second entry.
1548 if (secondEntry.contains("*")) { // There are three or more entries.
1549 // Get the index of the wildcard.
1550 val secondWildcardIndex = secondEntry.indexOf("*")
1552 // Split the entry into components.
1553 val realSecondEntry = secondEntry.substring(0, secondWildcardIndex)
1554 val thirdEntry = secondEntry.substring(secondWildcardIndex + 1)
1556 // Process the third entry.
1557 if (thirdEntry.contains("*")) { // There are four or more entries.
1558 // Get the index of the wildcard.
1559 val thirdWildcardIndex = thirdEntry.indexOf("*")
1561 // Split the entry into components.
1562 val realThirdEntry = thirdEntry.substring(0, thirdWildcardIndex)
1563 val fourthEntry = thirdEntry.substring(thirdWildcardIndex + 1)
1565 // Process the fourth entry.
1566 if (fourthEntry.contains("*")) { // Main block list quintuple entry.
1567 // Get the index of the wildcard.
1568 val fourthWildcardIndex = fourthEntry.indexOf("*")
1570 // Split the entry into components.
1571 val realFourthEntry = fourthEntry.substring(0, fourthWildcardIndex)
1572 val fifthEntry = fourthEntry.substring(fourthWildcardIndex + 1)
1574 // Create an entry string array.
1575 val quintupleEntry = arrayOf(firstEntry, realSecondEntry, realThirdEntry, realFourthEntry, fifthEntry, originalFilterListEntry)
1577 // Add the entry to the block list.
1578 mainBlockList.add(quintupleEntry)
1580 //Log.i("FilterLists", headers.get(1)[0] + " main block list added: " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " + realFourthEntry + " , " +
1581 // fifthEntry + " - " + originalFilterListEntry)
1582 } else { // Main block list quadruple entry.
1583 // Create an entry string array.
1584 val quadrupleEntry = arrayOf(firstEntry, realSecondEntry, realThirdEntry, fourthEntry, originalFilterListEntry)
1586 // Add the entry to the block list.
1587 mainBlockList.add(quadrupleEntry)
1589 //Log.i("FilterLists", headers.get(1)[0] + " main block list added: " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " + fourthEntry + " - " +
1590 // originalFilterListEntry)
1592 } else { // Main block list triple entry.
1593 // Create an entry string array.
1594 val tripleEntry = arrayOf(firstEntry, realSecondEntry, thirdEntry, originalFilterListEntry)
1596 // Add the entry to the block list.
1597 mainBlockList.add(tripleEntry)
1599 //Log.i("FilterLists", headers.get(1)[0] + " main block list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + " - " + originalFilterListEntry)
1601 } else { // Main block list double entry.
1602 // Create an entry string array.
1603 val doubleEntry = arrayOf(firstEntry, secondEntry, originalFilterListEntry)
1605 // Add the entry to the block list.
1606 mainBlockList.add(doubleEntry)
1608 //Log.i("FilterLists", headers.get(1)[0] + " main block list added: " + firstEntry + " , " + secondEntry + " - " + originalFilterListEntry)
1610 } else if (filterListEntry.isNotBlank()){ // Main block list single entry.
1611 // Create an entry string array.
1612 val singleEntry = arrayOf(filterListEntry, originalFilterListEntry)
1614 // Add the entry to the block list.
1615 mainBlockList.add(singleEntry)
1617 //Log.i("FilterLists", headers.get(1)[0] + " main block list added: " + filterListEntry + " - " + originalFilterListEntry)
1618 } else { // The entry is blank (empty or all white spaces).
1621 //Log.i("FilterLists", "${headers[1][0]} not added: $filterListEntry, $originalFilterListEntry")
1626 // Close the buffered reader.
1627 bufferedReader.close()
1628 } catch (e: IOException) {
1632 // Initialize the combined list.
1633 val combinedLists = ArrayList<List<Array<String>>>()
1635 // Add the headers (0).
1636 combinedLists.add(headers) // 0.
1638 // Add the allow lists (1-8).
1639 combinedLists.add(mainAllowList) // 1.
1640 combinedLists.add(finalAllowList) // 2.
1641 combinedLists.add(domainAllowList) // 3.
1642 combinedLists.add(domainInitialAllowList) // 4.
1643 combinedLists.add(domainFinalAllowList) // 5.
1644 combinedLists.add(thirdPartyAllowList) // 6.
1645 combinedLists.add(thirdPartyDomainAllowList) // 7.
1646 combinedLists.add(thirdPartyDomainInitialAllowList) // 8.
1648 // Add the block lists (9-22).
1649 combinedLists.add(mainBlockList) // 9.
1650 combinedLists.add(initialBlockList) // 10.
1651 combinedLists.add(finalBlockList) // 11.
1652 combinedLists.add(domainBlockList) // 12.
1653 combinedLists.add(domainInitialBlockList) // 13.
1654 combinedLists.add(domainFinalBlockList) // 14.
1655 combinedLists.add(domainRegularExpressionBlockList) // 15.
1656 combinedLists.add(thirdPartyBlockList) // 16.
1657 combinedLists.add(thirdPartyInitialBlockList) // 17.
1658 combinedLists.add(thirdPartyDomainBlockList) // 18.
1659 combinedLists.add(thirdPartyDomainInitialBlockList) // 19.
1660 combinedLists.add(thirdPartyRegularExpressionBlockList) // 20.
1661 combinedLists.add(thirdPartyDomainRegularExpressionBlockList) // 21.
1662 combinedLists.add(regularExpressionBlockList) // 22.
1664 // Return the combined lists.
1665 return combinedLists