// Application headers.
#include "FilterListHelper.h"
+#include "structs/OverrideStruct.h"
// Qt toolkit headers.
#include <QDebug>
ALLOWED_STRING = i18nc("Allowed disposition", "Allowed");
BLOCKED_STRING = i18nc("Blocked disposition", "Blocked");
+ // Populate the translated filter option disposition strings. Translated entries cannot be public static const.
+ FILTER_OPTION_NULL = QString();
+ FILTER_OPTION_APPLY = i18nc("Apply filter option", "Apply");
+ FILTER_OPTION_OVERRIDE = i18nc("Override filter option", "Override");
+
// Populate the translated navigation type strings. Translated entries cannot be public static const.
NAVIGATION_TYPE_LINK = i18nc("Navigation type link", "Link");
NAVIGATION_TYPE_TYPED = i18nc("Navigation type typed", "Typed");
RESOURCE_TYPE_UNKNOWN = i18nc("Resource type unknown", "Unknown");
// Populate the translated sublist strings. Translated entries cannot be public static const.
+ MAIN_ALLOWLIST_STRING = i18nc("Main allowlist sublist", "Main Allow List");
MAIN_BLOCKLIST_STRING = i18nc("Main blocklist sublist", "Main Block List");
+ INITIAL_DOMAIN_BLOCKLIST_STRING = i18nc("Initial domain blocklist string", "Initial Domain Block List");
// Populate the filter lists.
ultraListStructPointer = populateFilterList(QLatin1String(":/filterlists/ultralist.txt"));
bool FilterListHelper::checkFilterLists(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer) const
{
- // Initiate a status tracker. If the tracker changes to false, all process of the request will be stopped.
- bool status = true;
+ // Initiate a continue checking tracker. If the tracker changes to false, all process of the request will be stopped.
+ bool continueChecking = true;
+
+ // Create a URL struct.
+ UrlStruct urlStruct;
+
+ // Get the URLs.
+ QUrl firstPartyUrl = urlRequestInfo.firstPartyUrl();
+ QUrl requestUrl = urlRequestInfo.requestUrl();
+
+ // Get the hosts.
+ QString firstPartyHost = firstPartyUrl.host();
+ QString requestHost = requestUrl.host();
+
+ // Determine if this is a third-party request.
+ urlStruct.isThirdPartyRequest = (firstPartyHost != requestHost);
+
+ // Get the request URL string.
+ urlStruct.urlString = requestUrl.toString();
+
+ // Create a URL string with separators.
+ urlStruct.urlStringWithSeparators = urlStruct.urlString;
+
+ // Replace the separators characters with `^`.
+ urlStruct.urlStringWithSeparators.replace(QLatin1Char(':'), QLatin1Char('^'));
+ urlStruct.urlStringWithSeparators.replace(QLatin1Char('/'), QLatin1Char('^'));
+ urlStruct.urlStringWithSeparators.replace(QLatin1Char('?'), QLatin1Char('^'));
+ urlStruct.urlStringWithSeparators.replace(QLatin1Char('='), QLatin1Char('^'));
+ urlStruct.urlStringWithSeparators.replace(QLatin1Char('&'), QLatin1Char('^'));
+
+ // Add a `^` to the end of the string.
+ urlStruct.urlStringWithSeparators.append(QLatin1Char('^'));
+
+ // Create truncated URL strings and initially populate it with the original URL strings.
+ urlStruct.truncatedUrlString = urlStruct.urlString;
+ urlStruct.truncatedUrlStringWithSeparators = urlStruct.urlStringWithSeparators;
+
+ // Get the index of the beginning of the fully qualified domain name.
+ int fqdnIndex = urlStruct.truncatedUrlString.indexOf(QLatin1String("://")) + 3;
+
+ // Truncate the URL to the beginning of the fully qualified domain name.
+ urlStruct.truncatedUrlString.remove(0, fqdnIndex);
+ urlStruct.truncatedUrlStringWithSeparators.remove(0, fqdnIndex);
// Check UltraList.
- status = checkIndividualList(urlRequestInfo, requestStructPointer, ultraListStructPointer);
+ continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, ultraListStructPointer);
- // check UltraPrivacy if the status is still true.
- if (status) {
- status = checkIndividualList(urlRequestInfo, requestStructPointer, ultraPrivacyStructPointer);
- }
+ // Check UltraPrivacy.
+ if (continueChecking)
+ continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, ultraPrivacyStructPointer);
- // Return the status.
- return status;
+ // Check EasyList.
+ if (continueChecking)
+ continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, easyListStructPointer);
+
+ // Check EasyPrivacy.
+ if (continueChecking)
+ continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, easyPrivacyStructPointer);
+
+ if (continueChecking)
+ continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, fanboyAnnoyanceStructPointer);
+
+ // Return the continue checking status.
+ return continueChecking;
}
-bool FilterListHelper::checkIndividualList(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, FilterListStruct *filterListStruct) const
+bool FilterListHelper::blockRequest(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, const QString &filterListTitle, const int sublistInt,
+ EntryStruct *entryStructPointer) const
{
- // Get the request URL.
- QUrl url = urlRequestInfo.requestUrl();
+ // Block the request.
+ urlRequestInfo.block(true);
- // Get the request URL string.
- QString urlString = url.toString();
+ // Populate the request struct.
+ populateRequestStruct(requestStructPointer, BLOCKED, filterListTitle, sublistInt, entryStructPointer);
+
+ // Log the block.
+ //qDebug().noquote().nospace() << "Blocked request: " << urlRequestInfo.firstPartyUrl() << ", Filter list entry: " << entryStructPointer->appliedEntry;
+
+ // Returning `false` stops all processing of the request.
+ return false;
+}
+
+bool FilterListHelper::checkIndividualList(QWebEngineUrlRequestInfo &urlRequestInfo, UrlStruct &urlStruct, RequestStruct *requestStructPointer, FilterListStruct *filterListStructPointer) const
+{
+ // Check the main allow list.
+ for (auto filterListEntry = filterListStructPointer->mainAllowList.begin(); filterListEntry != filterListStructPointer->mainAllowList.end(); ++filterListEntry)
+ {
+ // Get the entry struct.
+ EntryStruct *entryStructPointer = *filterListEntry;
+
+ // TODO. Temporarily ignore empty applied entries.
+ if (!entryStructPointer->appliedEntry.isEmpty())
+ {
+ // Check if the URL string contains the applied entry.
+ if (urlStruct.urlString.contains(entryStructPointer->appliedEntry) || urlStruct.urlStringWithSeparators.contains(entryStructPointer->appliedEntry))
+ {
+ // Allow the request.
+ urlRequestInfo.block(false);
+
+ // Populate the request struct.
+ populateRequestStruct(requestStructPointer, ALLOWED, filterListStructPointer->title, MAIN_ALLOWLIST, entryStructPointer);
+
+ // Log the allow.
+ //qDebug().noquote().nospace() << "Allowed request: " << urlStruct.urlString << ", Filter list entry: " << entryStructPointer->appliedEntry;
+
+ // Returning `false` stops all processing of the request.
+ return false;
+ }
+ }
+ }
// Check the main block list.
- for (auto filterListEntry = filterListStruct->mainBlockList.begin(); filterListEntry != filterListStruct->mainBlockList.end(); ++filterListEntry) {
+ for (auto filterListEntry = filterListStructPointer->mainBlockList.begin(); filterListEntry != filterListStructPointer->mainBlockList.end(); ++filterListEntry)
+ {
// Get the entry struct.
EntryStruct *entryStructPointer = *filterListEntry;
- // Check if the URL string contains the applied entry
- if (urlString.contains(entryStructPointer->appliedEntry)) {
- // Block the request.
- urlRequestInfo.block(true);
+ // TODO. Temporarily ignore empty applied entries.
+ if (!entryStructPointer->appliedEntry.isEmpty())
+ {
+ // Check if the URL string contains the applied entry.
+ if (urlStruct.urlString.contains(entryStructPointer->appliedEntry) || urlStruct.urlStringWithSeparators.contains(entryStructPointer->appliedEntry))
+ {
+ // Check the third-party status.
+ bool continueChecking = checkThirdParty(urlRequestInfo, requestStructPointer, urlStruct.isThirdPartyRequest, filterListStructPointer->title, MAIN_BLOCKLIST, entryStructPointer);
- // Populate the request struct.
- populateRequestStruct(requestStructPointer, BLOCKED, filterListStruct->title, MAIN_BLOCKLIST, entryStructPointer->appliedEntry, entryStructPointer->originalEntry);
+ // Stop processing the filter lists if continue checking is `false`. Returning false halts all processing at upper levels.
+ if (continueChecking == false)
+ return false;
+ }
+ }
+ }
+
+ // Check the initial domain block list.
+ for (auto filterListEntry = filterListStructPointer->initialDomainBlockList.begin(); filterListEntry != filterListStructPointer->initialDomainBlockList.end(); ++filterListEntry)
+ {
+ // Get the entry struct.
+ EntryStruct *entryStructPointer = *filterListEntry;
- // Log the block.
- //qDebug().noquote().nospace() << "Blocked request: " << urlString << ", Filter list entry: " << entryStructPointer->appliedEntry;
+ // Check if the truncated URL string begins with the applied entry.
+ if (urlStruct.truncatedUrlString.startsWith(entryStructPointer->appliedEntry) || urlStruct.truncatedUrlStringWithSeparators.startsWith(entryStructPointer->appliedEntry))
+ {
+ // Check the third-party status.
+ bool continueChecking = checkThirdParty(urlRequestInfo, requestStructPointer, urlStruct.isThirdPartyRequest, filterListStructPointer->title, INITIAL_DOMAIN_BLOCKLIST, entryStructPointer);
- // Returning `false` stops all processing of the request.
- return false;
+ // Stop processing the filter lists if continue checking is `false`. Returning false halts all processing at upper levels.
+ if (continueChecking == false)
+ return false;
}
}
return true;
}
+bool FilterListHelper::checkThirdParty(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, const bool isThirdPartyRequest, const QString &filterListTitle,
+ const int sublistInt, EntryStruct *entryStructPointer) const
+{
+ // Check third-party status.
+ if (entryStructPointer->thirdParty == FilterOptionEnum::Disposition::Null) // Ignore third-party status.
+ {
+ // Check if filter options are applied.
+ if (entryStructPointer->hasFilterOptions) // Filter options are applied.
+ {
+ // Process the filter options.
+ return processFilterOptions(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+ else // Filter options are not applied.
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+ }
+ else if ((entryStructPointer->thirdParty == FilterOptionEnum::Disposition::Apply) && isThirdPartyRequest) // Block third-party request.
+ {
+ // Check if filter options are applied.
+ if (entryStructPointer->hasFilterOptions) // Filter options are applied.
+ {
+ // Process the filter options.
+ return processFilterOptions(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+ else // Filter options are not applied.
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+ }
+ else if ((entryStructPointer->thirdParty == FilterOptionEnum::Disposition::Override) && !isThirdPartyRequest) // Block first-party requests.
+ {
+ // Check if filter options are applied.
+ if (entryStructPointer->hasFilterOptions) // Filter options are applied.
+ {
+ // Process the filter options.
+ return processFilterOptions(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+ else // Filter options are not applied.
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+ }
+
+ // Returning `true` continues to process the filter lists. Returning `false` halts all processing of the filter lists.
+ return true;
+}
+
QString FilterListHelper::getDispositionString(int dispositionInt) const
{
// Return the translated disposition string.
}
}
+QString FilterListHelper::getFilterOptionDispositionString(const FilterOptionEnum::Disposition filterOptionDisposition) const
+{
+ // Return the translated filter option disposition string.
+ switch (filterOptionDisposition)
+ {
+ case FilterOptionEnum::Disposition::Apply: return FILTER_OPTION_APPLY;
+ case FilterOptionEnum::Disposition::Override: return FILTER_OPTION_OVERRIDE;
+ default: return FILTER_OPTION_NULL;
+ }
+}
+
QString FilterListHelper::getNavigationTypeString(int navigationTypeInt) const
{
// Return the translated navigation type string.
// Return the name of the requested sublist.
switch (sublistInt)
{
+ case MAIN_ALLOWLIST: return MAIN_ALLOWLIST_STRING;
case MAIN_BLOCKLIST: return MAIN_BLOCKLIST_STRING;
+ case INITIAL_DOMAIN_BLOCKLIST: return INITIAL_DOMAIN_BLOCKLIST_STRING;
default: return QString(); // The default return should never be reached.
}
}
entryStructPointer->originalEntry = filterListString;
// Process the entry.
- if (filterListString.startsWith(QLatin1Char('['))) { // The line starts with `[`, which is the file format.
+ if (filterListString.isEmpty()) // Ignore empty lines.
+ {
+ // Do nothing.
+
+ // Log the dropping of the line.
+ //qDebug().noquote().nospace() << filterListString << " NOT added from " << filterListFileName << " (empty line).";
+ }
+ else if (filterListString.startsWith(QLatin1Char('['))) // The line starts with `[`, which is the file format.
+ {
// Do nothing.
// Log the dropping of the line.
- //qDebug().noquote().nospace() << filterListString << " NOT added from " << filterListFileName;
- } else if (filterListString.startsWith(QLatin1Char('!'))) { // The line starts with `!`, which are comments.
+ //qDebug().noquote().nospace() << filterListString << " NOT added from " << filterListFileName << " (file format).";
+ }
+ else if (filterListString.contains(QLatin1String("##")) ||
+ filterListString.contains(QLatin1String("#?#")) ||
+ filterListString.contains(QLatin1String("#@#")) ||
+ filterListString.contains(QLatin1String("#$#"))) // The line contains unimplemented content filtering.
+ {
+ // Do nothing.
+
+ // Log the dropping of the line.
+ //qDebug().noquote().nospace() << filterListString << " NOT added from " << filterListFileName << " (content filtering).";
+ }
+ else if (filterListString.startsWith(QLatin1Char('!'))) // The line starts with `!`, which are comments.
+ {
if (filterListString.startsWith(QLatin1String("! Title: "))) // The line contains the title.
{
// Add the title to the filter list struct.
// Log the dropping of the line.
//qDebug().noquote().nospace() << originalFilterListString << " NOT added from " << filterListFileName;
- } else { // Process the entry.
- // Add the applied entry to the struct.
- entryStructPointer->appliedEntry = filterListString;
+ }
+ else // Process the filter options.
+ {
+ // Split any filter options from the end of the string.
+ QStringList splitEntryStringList = filterListString.split(QLatin1Char('$'));
+
+ // Store the entry without the filter options as the filter list string.
+ filterListString = splitEntryStringList[0];
+
+ // Create a popup only filter option tracker.
+ bool popupOnlyFilterOption = false;
+
+ // Process the filter options if they exist.
+ if (splitEntryStringList.size() > 1)
+ {
+ // Store the filter options.
+ entryStructPointer->filterOptions = splitEntryStringList[1];
+
+ // Split the filter options.
+ QStringList filterOptionsList = splitEntryStringList[1].split(QLatin1Char(','));
+
+ // Check if the entry has a single popup filter option as Qt WebEngine doesn't know how to process them.
+ if ((filterOptionsList.size() == 1) && (filterOptionsList[0] == QLatin1String("popup"))) // This entry has a single popup filter option.
+ {
+ // Set the popup only filter option flag.
+ popupOnlyFilterOption = true;
+ }
+ else // This entry has filter options besides popup.
+ {
+ // Initialize an override struct.
+ OverrideStruct overrideStruct;
+
+ // Populate the filter options entries.
+ foreach (QString filterOption, filterOptionsList)
+ {
+ // Populate the third-party options.
+ if (filterOption == QLatin1String("third-party")) entryStructPointer->thirdParty = FilterOptionEnum::Disposition::Apply;
+ if (filterOption == QLatin1String("~third-party")) entryStructPointer->thirdParty = FilterOptionEnum::Disposition::Override;
+
+ // Populate the filter options.
+ if (filterOption == QLatin1String("document"))
+ {
+ // Populate the main frame option.
+ entryStructPointer->mainFrame = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("font"))
+ {
+ // Populate the font option.
+ entryStructPointer->font = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("image"))
+ {
+ // Populate the image option.
+ entryStructPointer->image = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("media"))
+ {
+ // Populate the media option.
+ entryStructPointer->media = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("object"))
+ {
+ // Populate the object option.
+ entryStructPointer->object = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("other"))
+ {
+ // Populate the other option.
+ entryStructPointer->other = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("ping"))
+ {
+ // Populate the ping option.
+ entryStructPointer->ping = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("script"))
+ {
+ // Populate the script option.
+ entryStructPointer->script = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("stylesheet"))
+ {
+ // Populate the script option.
+ entryStructPointer->styleSheet = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("subdocument"))
+ {
+ // Populate the sub resource option.
+ entryStructPointer->subFrame = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("xmlhttprequest"))
+ {
+ //Populate the XML HTTP request option.
+ entryStructPointer->xmlHttpRequest = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ // Populate the override struct.
+ if (filterOption == QLatin1String("~document"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.mainFrame = true;
+ }
+
+ if (filterOption == QLatin1String("~font"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.font = true;
+ }
+
+ if (filterOption == QLatin1String("~image"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.image = true;
+ }
+
+ if (filterOption == QLatin1String("~media"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.media = true;
+ }
+
+ if (filterOption == QLatin1String("~object"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.object = true;
+ }
+
+ if (filterOption == QLatin1String("~other"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.other = true;
+ }
+
+ if (filterOption == QLatin1String("~ping"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.ping = true;
+ }
+
+ if (filterOption == QLatin1String("~script"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.script = true;
+ }
+
+ if (filterOption == QLatin1String("~stylesheet"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.styleSheet = true;
+ }
+
+ if (filterOption == QLatin1String("~subdocument"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.subFrame = true;
+ }
+
+ if (filterOption == QLatin1String("~xmlhttprequest"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.xmlHttpRequest = true;
+ }
+ }
+
+ // Apply the overrides.
+ if (overrideStruct.hasOverride)
+ {
+ // Font.
+ if (overrideStruct.font)
+ entryStructPointer->font = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->font = FilterOptionEnum::Disposition::Apply;
+
+ // Image.
+ if (overrideStruct.image)
+ entryStructPointer->image = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->image = FilterOptionEnum::Disposition::Apply;
+
+ // Main Frame (document).
+ if (overrideStruct.mainFrame)
+ entryStructPointer->mainFrame = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->mainFrame = FilterOptionEnum::Disposition::Apply;
+
+ // Media.
+ if (overrideStruct.media)
+ entryStructPointer->media = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->media = FilterOptionEnum::Disposition::Apply;
+
+ // Object.
+ if (overrideStruct.object)
+ entryStructPointer->object = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->object = FilterOptionEnum::Disposition::Apply;
+
+ // Other.
+ if (overrideStruct.other)
+ entryStructPointer->other = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->other = FilterOptionEnum::Disposition::Apply;
+
+ // Ping.
+ if (overrideStruct.ping)
+ entryStructPointer->ping = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->ping = FilterOptionEnum::Disposition::Apply;
+
+ // Script.
+ if (overrideStruct.script)
+ entryStructPointer->script = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->script = FilterOptionEnum::Disposition::Apply;
+
+ // Style Sheet.
+ if (overrideStruct.styleSheet)
+ entryStructPointer->styleSheet = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->styleSheet = FilterOptionEnum::Disposition::Apply;
+
+ // Sub Resource.
+ if (overrideStruct.subFrame)
+ entryStructPointer->subFrame = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->subFrame = FilterOptionEnum::Disposition::Apply;
+
+ // XML HTTP Request.
+ if (overrideStruct.xmlHttpRequest)
+ entryStructPointer->xmlHttpRequest = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->xmlHttpRequest = FilterOptionEnum::Disposition::Apply;
+ }
+ }
+ }
+
+ // Drop entries that only have a single popup filter option as Qt WebEngine doesn't know how to process them.
+ if (popupOnlyFilterOption) // This entry has a single popup filter option.
+ {
+ // Do nothing.
+
+ // Log the dropping of the line.
+ //qDebug().noquote().nospace() << entryStructPointer->originalEntry << " NOT added from " << filterListFileName << " (single popup filter option).";
+ }
+ else if (filterListString.startsWith(QLatin1String("@@"))) // Process an allow list entry.
+ {
+ // Remove the initial `@@`.
+ filterListString.remove(0, 2);
- // Add the filter list entry struct to the main block list.
- filterListStructPointer->mainBlockList.push_front(entryStructPointer);
+ // Remove any initial and trailing asterisks.
+ removeInitialAndTrailingAsterisks(filterListString);
- // Log the addition to the filter list.
- //qDebug().noquote().nospace() << originalFilterListString << " added from " << filterListFileName;
+ // Add the applied entry to the struct.
+ entryStructPointer->appliedEntry = filterListString;
+
+ // Add the filter list entry struct to the main allow list.
+ filterListStructPointer->mainAllowList.push_front(entryStructPointer);
+
+ // Log the addition to the filter list.
+ //qDebug().noquote().nospace() << entryStructPointer->originalEntry << " added to Main Allow List from " << filterListFileName << ".";
+ }
+ else if (filterListString.startsWith(QLatin1String("||"))) // Process an initial domain allow list entry.
+ {
+ // Remove the initial `||`.
+ filterListString.remove(0, 2);
+
+ // Add the applied entry to the struct.
+ entryStructPointer->appliedEntry = filterListString;
+
+ // Add the filter list entry struct to the initial domain block list.
+ filterListStructPointer->initialDomainBlockList.push_front(entryStructPointer);
+
+ // Log the addition to the filter list.
+ //qDebug().noquote().nospace() << entryStructPointer->originalEntry << " added to Initial Domain Block List from " << filterListFileName << ".";
+ }
+ else // Process a block list entry.
+ {
+ // Remove any initial and trailing asterisks.
+ removeInitialAndTrailingAsterisks(filterListString);
+
+ // Add the applied entry to the struct.
+ entryStructPointer->appliedEntry = filterListString;
+
+ // Add the filter list entry struct to the main block list.
+ filterListStructPointer->mainBlockList.push_front(entryStructPointer);
+
+ // Log the addition to the filter list.
+ //qDebug().noquote().nospace() << entryStructPointer->originalEntry << " added to Main Block List from " << filterListFileName << ".";
+ }
}
}
return filterListStructPointer;
}
-void FilterListHelper::populateRequestStruct(RequestStruct *requestStructPointer, const int disposition, const QString &filterListTitle, const int sublistInt, const QString &appliedEntry,
- const QString &originalEntry) const
+void FilterListHelper::populateRequestStruct(RequestStruct *requestStructPointer, const int disposition, const QString &filterListTitle, const int sublistInt, EntryStruct *entryStructPointer) const
{
// Populate the request struct.
requestStructPointer->dispositionInt = disposition;
requestStructPointer->filterListTitle = filterListTitle;
requestStructPointer->sublistInt = sublistInt;
- requestStructPointer->entryStruct.appliedEntry = appliedEntry;
- requestStructPointer->entryStruct.originalEntry = originalEntry;
+ requestStructPointer->entryStruct.appliedEntry = entryStructPointer->appliedEntry;
+ requestStructPointer->entryStruct.originalEntry = entryStructPointer->originalEntry;
+}
+
+bool FilterListHelper::processFilterOptions(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, const QString &filterListTitle, const int sublistInt,
+ EntryStruct *entryStructPointer) const
+{
+ // Block font requests.
+ if ((entryStructPointer->font == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeFontResource))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block image requests.
+ if ((entryStructPointer->image == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeImage))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block main frame requests.
+ if ((entryStructPointer->mainFrame == FilterOptionEnum::Disposition::Apply) && ((requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeMainFrame) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeNavigationPreloadMainFrame)))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block media requests.
+ if ((entryStructPointer->media == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeMedia))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block object requests.
+ if ((entryStructPointer->object == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeObject))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block other requests.
+ if ((entryStructPointer->other == FilterOptionEnum::Disposition::Apply) && ((requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeSubResource) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeWorker) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeSharedWorker) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypePrefetch) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeFavicon) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeServiceWorker) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeCspReport) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypePluginResource) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeUnknown)))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block ping requests
+ if ((entryStructPointer->ping == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypePing))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block script requests.
+ if ((entryStructPointer->script == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeScript))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block style sheet requests.
+ if ((entryStructPointer->styleSheet == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeStylesheet))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block sub resource requests.
+ if ((entryStructPointer->subFrame == FilterOptionEnum::Disposition::Apply) && ((requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeSubFrame) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeNavigationPreloadSubFrame)))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block XML HTTP requests.
+ if ((entryStructPointer->xmlHttpRequest == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeXhr))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Returning true continues processing the filter list.
+ return true;
+}
+
+void FilterListHelper::removeInitialAndTrailingAsterisks(QString &filterListEntry) const
+{
+ // Remove the initial asterisk if it exists.
+ if (filterListEntry.startsWith(QLatin1Char('*')))
+ filterListEntry.remove(0, 1);
+
+ // Remove the final asterisk if it exists.
+ if (filterListEntry.endsWith(QLatin1Char('*')))
+ filterListEntry.chop(1);
}