aboutsummaryrefslogtreecommitdiff
path: root/staging/adblock/options.cpp
blob: 08f30eeac1bdaf130312c43511051749cfc8fec5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*
 * This file is part of smolbote. It's copyrighted by the contributors recorded
 * in the version control history of the file, available from its original
 * location: https://library.iserlohn-fortress.net/aqua/smolbote.git
 *
 * SPDX-License-Identifier: GPL-3.0
 */

#include "options.h"

using namespace AdblockPlus;

constexpr std::array abpTypeOptions = {
    "document", //              ResourceTypeMainFrame	        0	Top level page.
    "subdocument", //           ResourceTypeSubFrame	        1	Frame or iframe.
    "stylesheet", //            ResourceTypeStylesheet	        2	A CSS stylesheet.
    "script", //                ResourceTypeScript	        3	An external script.
    "image", //                 ResourceTypeImage	        4	An image (JPG, GIF, PNG, and so on).
    "font", //                  ResourceTypeFontResource	5	A font.
    "other", //                 ResourceTypeSubResource	        6	An "other" subresource.
    "object", //                ResourceTypeObject	        7	An object (or embed) tag for a plugin or a resource that a plugin requested.
    "media", //                 ResourceTypeMedia	        8	A media resource.
    "__worker", //              ResourceTypeWorker	        9	The main resource of a dedicated worker.
    "__sharedworker", //        ResourceTypeSharedWorker	10	The main resource of a shared worker.
    "__prefetch", //            ResourceTypePrefetch	        11	An explicitly requested prefetch.
    "__favicon", //             ResourceTypeFavicon	        12	A favicon.
    "xmlhttprequest", //        ResourceTypeXhr	                13	An XMLHttpRequest.
    "ping", //                  ResourceTypePing	        14	A ping request for <a ping>.
    "__serviceworker", //       ResourceTypeServiceWorker	15	The main resource of a service worker.
    "__cspreport", //           ResourceTypeCspReport	        16	A report of Content Security Policy (CSP) violations.
    "__pluginresource", //      ResourceTypePluginResource	17	A resource requested by a plugin.
    "__preloadmainframe", //    ResourceTypeNavigationPreloadMainFrame	19	A main-frame service worker navigation preload request.
    "__preloadsubframe", //     ResourceTypeNavigationPreloadSubFrame	20	A sub-frame service worker navigation preload request.
    "__unknown" //              ResourceTypeUnknown	        255	Unknown request type.
};

auto parseTypeOption(QStringRef &option)
{
    struct {
        bool found = false;
        int index = -1;
        bool exception = false;
    } ret;

    // Possible inverse type options include ~script, ~image, ~stylesheet, ~object,
    // ~xmlhttprequest, ~subdocument, ~ping, ~websocket, ~webrtc, ~document, ~elemhide, ~other
    if(option[0] == '~') {
        ret.exception = true;
        option = option.mid(1);
    }

    // TODO: map all ResourceType's to their respective strings
    // TODO: websocket, webrtc, elemhide, generichide, genericblock, popup

    for(std::size_t i = 0; i < std::size(abpTypeOptions); ++i) {
        if(option == abpTypeOptions[i]) {
            ret.index = i;
            ret.found = true;
            return ret;
        }
    }
    return ret;
}

bool Options::parseAbp(const QStringRef &options)
{
    std::bitset<32> checked_flags;

    for(auto &option : options.split(',')) {
        if(option == "match-case") {
            matchcase = true;

        } else if(option == "third-party") {
            thirdparty = !exception;
        } else if(const auto r = parseTypeOption(option); r.found) {
            if(!r.exception) {
                flags.set(r.index, true);
                checked_flags.set(r.index, true);
            } else {
                flags.set(r.index, false);
                checked_flags.set(r.index, true);
                for(auto i = 0; i < 32; ++i) {
                    if(!checked_flags[i]) {
                        flags.set(i, true);
                    }
                }
            }
        } else {
            return false;
        }
    }

    return true;
}